mapeo ejemplo datos java hibernate orm java-ee ibatis

java - ejemplo de mapeo de base de datos



Hibernate, iBatis, Java EE u otra herramienta ORM de Java (12)

Estamos en el proceso de planear una gran aplicación empresarial. Estamos centrando nuestros esfuerzos en evaluar hibernate después de experimentar los dolores de J2EE.

Parece que la nueva API de Java EE es más simple. También he leído algunas cosas buenas sobre Hibernate e iBatis. Nuestro equipo tiene poca experiencia con cualquiera de los marcos.

Hay 5 puntos principales de comparación que me gustaría determinar

  • Curva de aprendizaje / facilidad de uso
  • Productividad
  • Mantenibilidad / Estabilidad
  • Rendimiento / escalabilidad
  • Facilidad de solución de problemas

Si tuviera que administrar un equipo de ~ 6 desarrolladores con experiencia en J2EE, ¿qué herramienta de ORM usaría y por qué?


¿Has intentado responder por qué incluso utilizar una herramienta ORM antes de decidir cuál usar? Si tiene personas en su equipo que conocen SQL, consulte a JDBC.


Actualmente estamos trabajando en un proyecto que utiliza tanto Hibernate como ibatis. ¿Por qué usar hibernate? Es compatible con nuestro modelo de dominio, relaciones y herencia. Tenemos un modelo de dominio bastante complejo y hiberante lo admite muy bien. No necesita preocuparse por escribir inserciones, actualizaciones, etc. Ibatis se usa solo para ver. Hay consultas y tenemos objetos de vista (similares a modelos de dominio pero no modelos de dominio) que se asignan con consultas. Ibatis devuelve los datos en la vista que desee sin preocuparse por leer el conjunto de resultados, que debe administrar en Spring JDBC. ¿Por qué nosotros que en lugar de usar HQl o Spring JDBC? El dominio es muy complejo y, al visualizar, hacemos cálculos, agrupamos y toneladas de funciones SQL nativas. hacemos todo eso en consultas, usamos consultas dinámicas, administramos condiciones en ibatis y obtenemos un objeto limpio y liviano. Tiene mucho más sentido si tiene que recorrer varias capas para buscar datos en hibernación. Dependiendo de su situación, es posible que desee usar solo uno, ambos o ninguno. Pero definitivamente, hibernar no es algo que no puedas vivir sin él.


Creo que debemos tener en cuenta la razón principal por la que estamos usando Java (u OO).

El sistema debe ser flexible y permitir modificaciones constantes de la especificación (esto sucede muy a menudo en la vida real). De lo contrario, deberíamos haber programado en C, porque es mucho más rápido.

Creo que la mejor pila para aplicaciones web sería Java EE: JPA - EJB - JSF (con una conversación de contexto de persistencia extendida con ámbito).

JSF también es más lento que el JSP / Servlet puro, pero es más rápido de desarrollar.

JPA es más difícil de aprender, pero es más rápido de desarrollar (ya sabes: RAD) y los cambios no tienen un gran impacto (copiar y pegar propenso a errores). Agregue una nueva columna en su entidad más utilizada, y tendrá que actualizar todas las declaraciones en iBatis ...

JPA no funciona muy bien en todos los casos, pero cubre la mayoría de ellos, y también le permite conectar Consulta nativa en lugar de JPQL sin cambiar ningún código. Pero si te encuentras escribiendo demasiado Native Query, tu proyecto podría encajar mejor con iBatis.

Y en cuanto a rendimiento, JPA también es eficiente si entiendes cómo se traduce a SQL, y si lo pones para hacer lo que mejor sabe hacer, si lo pones para hacer algo que no es cómodo para él, generará demasiadas consultas . ¡No hay magia! Debe tener en cuenta la consulta generada, no a ciegas esperar que pueda tomar el camino fácil cuando aparezca un caso complicado.

Además, si los desarrolladores tienen todas las capacidades de SQL, escribirán consultas demasiado complejas para procesar la lógica de negocios, en lugar de tenerlas en un lugar centralizado, tendrá cierta lógica de negocios en SQL, algunas en EJB. JPA debe ser para persistir en su modelo, no para Business Logic.

La consulta de criterios tampoco es compatible para crear consultas dinámicas nomatterhowcomplex seguras.


Déjame analizar esto. En primer lugar, he escrito algunos sobre este tema en Uso de un ORM o SQL simple? . Específicamente para abordar sus puntos:

Curva de aprendizaje / facilidad de uso

Ibatis es sobre SQL. Si conoce SQL, la curva de aprendizaje para ibatis es trivial. Ibatis hace algunas cosas sobre SQL tales como:

  • agrupar por;
  • tipos discriminados; y
  • SQL dinámico

que todavía necesitarás aprender, pero el mayor obstáculo es SQL.

JPA (que incluye Hibernate), por otro lado, intenta distanciarse de SQL y presentar cosas en un objeto en lugar de una forma relacional. Sin embargo, como señala Joel, las abstracciones tienen filtraciones y JPA no es una excepción. Para hacer JPA, aún necesitará conocer modelos relacionales, SQL, ajuste de rendimiento de consultas, etc.

Mientras que Ibatis simplemente te hará aplicar el SQL que conoces o estás aprendiendo, JPA requerirá que sepas algo más: cómo configurarlo (ya sea XML o anotaciones). Con esto me refiero a entender que las relaciones de clave externa son una relación (uno a uno, uno a muchos o muchos a muchos) de algún tipo, el mapeo tipo, etc.

Si conoces SQL, diría que la barrera para aprender JPA es realmente mayor. Si no lo hace, es más un resultado mixto con JPA lo que le permite diferir el aprendizaje de SQL por un tiempo (pero no lo pospone indefinidamente).

Con JPA una vez que configura sus entidades y sus relaciones, entonces otros desarrolladores pueden simplemente usarlas y no necesitan aprender todo sobre la configuración de JPA. Esto podría ser una ventaja, pero un desarrollador aún tendrá que saber acerca de los administradores de entidades, la gestión de transacciones, los objetos gestionados frente a los no gestionados, etc.

Vale la pena señalar que JPA también tiene su propio lenguaje de consulta (JPA-SQL), que tendrá que aprender si conoce SQL o no. Encontrará situaciones en las que JPA-SQL simplemente no puede hacer las cosas que SQL puede hacer.

Productividad

Esto es difícil de juzgar. Personalmente, creo que soy más productivo en ibatis, pero también estoy muy cómodo con SQL. Algunos argumentarán que son mucho más productivos con Hibernate, pero posiblemente esto se deba, al menos en parte, a la falta de familiaridad con SQL.

Además, la productividad con JPA es engañosa porque ocasionalmente se encontrará con un problema con su modelo de datos o consultas que le llevará medio día o un día resolver a medida que sube el registro y ver qué SQL está produciendo su proveedor de JPA y luego trabajando la combinación de configuraciones y llamadas para lograr que produzca algo que sea correcto y eficiente.

Simplemente no tiene este tipo de problema con Ibatis porque ha escrito el SQL usted mismo. Lo prueba ejecutando el SQL dentro de PL / SQL Developer, SQL Server Management Studio, Navicat for MySQL o lo que sea. Una vez que la consulta es correcta, todo lo que hace es asignar entradas y salidas.

También descubrí que JPA-QL es más incómodo que el SQL puro. Necesita herramientas separadas para ejecutar una consulta JPA-QL para ver los resultados y es algo más que debe aprender. De hecho, encontré esta parte de JPA bastante incómoda y difícil de manejar, aunque a algunas personas les encanta.

Mantenibilidad / Estabilidad

El peligro con Ibatis es la proliferación, lo que significa que su equipo de desarrollo puede seguir agregando objetos de valor y consultas a medida que los necesita en lugar de buscar la reutilización mientras que JPA tiene una entidad por tabla y una vez que tiene esa entidad, eso es todo. Las consultas con nombre tienden a ir en esa entidad, por lo que es difícil pasar por alto. Las consultas ad-hoc aún se pueden repetir, pero creo que es un problema menor.

Sin embargo, eso tiene un costo de rigidez. A menudo, en una aplicación, necesitará fragmentos de datos de diferentes tablas. Con SQL es fácil porque puede escribir una sola consulta (o un pequeño número de consultas) para obtener toda esa información en un solo golpe y colocarla en un objeto de valor personalizado solo para ese propósito.

Con JPA, estás moviendo esa lógica hacia tu capa de negocios. Las entidades son básicamente todo o nada. Ahora eso no es estrictamente cierto. Varios proveedores de JPA le permitirán cargar parcialmente entidades y demás, pero incluso allí están hablando de las mismas entidades discretas. Si necesita datos de 4 tablas, necesita 4 entidades o necesita combinar los datos que desea con algún tipo de objeto de valor personalizado en el negocio o en la capa de presentación.

Otra cosa que me gusta de ibatis es que todo su SQL es externo (en archivos XML). Algunos citarán que esto es una desventaja, pero no yo. A continuación, puede encontrar los usos de una tabla y / o columna relativamente fácil buscando en sus archivos XML. Con SQL incrustado en el código (o donde no hay ningún SQL), puede ser mucho más difícil de encontrar. También puede cortar y pegar SQL en una herramienta de base de datos y ejecutarlo. No puedo exagerar lo suficiente cuántas veces me ha sido útil a lo largo de los años.

Rendimiento / escalabilidad

Aquí creo que ibatis gana victoriosamente. Es SQL directo y bajo costo. Por su naturaleza, JPA simplemente no podrá gestionar el mismo nivel de latencia o rendimiento. Ahora lo que JPA tiene a su favor es que la latencia y el rendimiento raramente son problemas. Sin embargo, existen sistemas de alto rendimiento que tenderán a desfavorecer más soluciones de peso pesado como JPA.

Además con ibatis, puede escribir una consulta que devuelva exactamente los datos que desea con las columnas exactas que necesita. Fundamentalmente, no hay forma de que JPA pueda vencer (o incluso hacer coincidir) eso cuando devuelve entidades discretas.

Facilidad de solución de problemas

Creo que este es un triunfo para Ibatis también. Como mencioné anteriormente, con JPA a veces pasará medio día obteniendo una consulta o entidad produciendo el SQL que desea o diagnosticando un problema donde una transacción falla porque el administrador de la entidad intentó persistir un objeto no administrado (que podría ser parte de un lote trabajo en el que has dedicado mucho trabajo, por lo que podría ser no trivial encontrarlo).

Ambos fallarán si intenta utilizar una tabla o columna que no existe, lo cual es bueno.

Otros criterios

Ahora no mencionó la portabilidad como uno de sus requisitos (lo que significa pasar de un proveedor de base de datos). Vale la pena señalar que aquí JPA tiene la ventaja. Las anotaciones son menos portátiles que, por ejemplo, Hibernate XML (por ejemplo, las anotaciones JPA estándar no tienen un equivalente para el tipo de ID "nativo" de Hibernate) pero ambas son más portátiles que ibatis / SQL.

También he visto que JPA / Hibernate se utiliza como una forma de DDL portátil, lo que significa que se ejecuta un pequeño programa de Java que crea el esquema de la base de datos desde la configuración de JPA. Con ibatis necesitará un script para cada base de datos compatible.

La desventaja de la portabilidad es que JPA es, de alguna manera, el denominador común más bajo, lo que significa que el comportamiento admitido es, en gran medida, el comportamiento común admitido en una amplia gama de proveedores de bases de datos. Si desea utilizar Oracle Analytics en ibatis, no hay problema. En JPA? Bueno, eso es un problema.


Ir con Hibernate. Su proyecto definitivamente crecerá más adelante y la inversión (en el aprendizaje hibernate) se amortizará de una forma u otra.


La solución que elija también depende de cuán obediente elija (o se requiera) para estar con la especificación Java EE. JPA es "el estándar" para el acceso a los datos en los sistemas Java EE, por lo que si desea adherirse a eso, debe usarlo (con algunas advertencias).

JPA es una estandarización de sistemas de mapeo relacional de objetos. Como tal, no proporciona una implementación, simplemente define un enfoque estandarizado. Hibernate Entity Manager es una de esas implementaciones.

Dado que JPA es un estándar en múltiples proveedores y dado que todavía es bastante nuevo, carece de algunas funcionalidades esotéricas más que son valiosas en algunos casos de uso (por ejemplo, una API Criteria para generar SQL dinámico). Si vas con el plan JPA en situaciones donde necesitarás usar Hibernate directamente, o incluso JDBC directamente. Para situaciones como esta, un patrón DAO genérico es muy útil; puede modificar este: Objetos de acceso a datos genéricos para usar en JPA y JDBC con bastante facilidad.

JPA tiene algunas restricciones difíciles (especialmente si estás acostumbrado a Hibernate), e impone ciertos enfoques sobre ti que son difíciles para los desarrolladores que están más acostumbrados a escribir JDBC directamente. Si defiende esto como un enfoque, asegúrese de hacer su tarea sobre los pros y contras de ORM vs. JDBC.

Si vas con JPA, una vez que alcanzas la curva de aprendizaje, te pagará en términos de desarrollo simple (particularmente si implementas correctamente el patrón DAO antes mencionado), pero también en obtener el almacenamiento en caché de niveles múltiples de los resultados de la consulta. Si se hace correctamente (un gran "si", lo sé), he visto que esto proporciona bonitos beneficios.

Por último, si tiene un modelo de datos heredado con el que tiene poca flexibilidad, Hibernate (y JPA) le dará más dolores de cabeza que quizás valga la pena. Por ejemplo:

  • Si la base de datos no tiene claves principales candidatas (para las implementaciones hashCode e iguales efectivas), tendrá que hacer un análisis inicial sobre qué columnas definen una fila de manera única, quizás simple, tal vez compleja dependiendo de la complejidad de su esquema;
  • Si no puede agregar columnas de versión o de marca de tiempo, pierde la capacidad de Hibernate para realizar un bloqueo optimista y termina teniendo que consultar antes de realizar la actualización.

(Agregado en respuesta al primer comentario) Si tiene la suerte de rediseñar su base de datos, dos consideraciones muy importantes si va a utilizar un ORM:

  • Agregue una columna de número de versión a todas las tablas relevantes para admitir el bloqueo optimista.
  • Durante su análisis de datos, decida sobre la (s) columna (s) de " clave alternativa " no anulable que los desarrolladores deberían usar para hashCode() & equals() . No use columnas PK en esos métodos.

Para agregar otra opción a la lista ... eche un vistazo a:

Ebean ORM ( http://ebean-orm.github.io ).

Su principal reclamo sería un modelo de programación más simple e intuitivo que JPA o Hibernate. Específicamente, no tiene una sesión de Hibernate o JPA EntityManager, no hay objetos separados / adjuntos (no fusionar, persistir, vaciar), la carga diferida simplemente funciona.

... alias es mucho más simple de usar y entender.

También puede usar su propio SQL con Ebean (para consultas, actualizaciones, procedimientos almacenados) y la IMO coincide con Ibatis en facilidad de uso usando su propio SQL.

Si buscas utilizar el ORM en Java SE, te sugiero que lo consultes.

  • Licencia LGPL
  • Use anotaciones JPA para mapeo (@Entity, @OneToMany, etc.)
  • API sin sesión (sin fusionar, persistir, vaciar ... guardar () y eliminar () en su lugar)
  • Soporte de "Objeto parcial"
  • Soporte de consultas grandes (por contexto de persistencia de gráfico de objetos)
  • Consultas de fondo
  • Buen soporte para el procesamiento por lotes
  • Afinación automática de consultas (a través de "Autofetch")

Saludos, Rob.


Si de hecho tiene un proyecto greenfield, puede utilizar hibernate, pero tenga en cuenta que la curva de aprendizaje es bastante empinada.

Si tiene una base de datos existente, es mucho mejor con iBatis, porque después de un día es productivo y después de dos días más puede saberlo al respecto.

Una cosa que debes tener en cuenta es que la API api de hibernación es excelente para crear consultas personalizadas, que según tu aplicación puede ser un buen argumento para ello.


Si no tiene un buen modelo de objetos, no veo el beneficio de Hibernate. Ciertamente tiene el "relacional" en ORM, ya que tiene una base de datos relacional, pero el "objeto" es la clave. Sin objetos, sin ORM. Creo que un mapeo 1: 1 entre objetos y tablas, sin un comportamiento más rico de los objetos, no justifica el ORM. Quédese con JDBC o iBatis si esa es su situación.


Sugeriría ir con JPA y dependiendo (¡en serio!) De la duración / alcance de su proyecto, así que podría consultar JPA2, ya que proporciona algunas de las características que faltan de JPA (una muy agradable API de consulta, por ejemplo).


Tenga en cuenta que el uso de JPA / Hibernate (y probablemente la mayoría de otras soluciones ORM) en aplicaciones multi-hilo no triviales puede convertirse rápidamente en un PITA real porque las sesiones de la base de datos deben limitarse exactamente a un hilo (los objetos Session no son seguros para subprocesos). Agregue carga diferida y el hecho de que las entidades persistentes pueden pertenecer, como máximo, a una sesión activa ... y tendrá que dar un gran paseo ...

Es posible que desee echarle un vistazo a la administración de la sesión usando Hibernate en una aplicación Swing * multiproceso * (o simplemente busque ''hibernar multiproceso'').

Mi regla general (YMMV): si la aplicación no se presta a algún tipo de ciclo de solicitud / respuesta (como un servicio web, por ejemplo), es probable que sea mejor que uses otra cosa.

Por supuesto, otra solución sería diseñar la aplicación de una manera que eluda las limitaciones del marco mencionado. Sin embargo, cambiar el diseño de una aplicación para que pueda hacer que funcione el framework XYZ deja un mal sabor de boca.

De todos modos, solo mi $ 0.02


Una regla empírica simplista entre iBatis e Hibernate es que si desea más vista SQL / relacional del mundo, iBatis se adapta mejor; y para una cadena de herencia más compleja, y una vista menos directa a SQL, Hibernate. Ambos son ampliamente utilizados y buenos marcos sólidos. Entonces creo que ambos probablemente funcionen bien. Quizás lea un tutorial para ambos, vea si uno suena mejor que el otro, y simplemente elija uno.

De las cosas que enumera, no creo que el rendimiento sea muy diferente: el cuello de botella casi invariablemente será la base de datos, no el marco. Por otras cosas, creo que los diferentes desarrolladores preferirían uno u otro, es decir, no hay una prioridad comúnmente aceptada (para iBatis vs Hibernate).