Persistencia en Java
En los últimos años, he acumulado experiencia en el campo de la abstracción de persistencia en Java, utilizando conceptos como EJB 2.0, Hibernate, JPA y los propios. Me parecieron tener una curva de aprendizaje empinada y mucha complejidad. Además, como gran fanático de SQL, también pensé que muchos modelos de abstracción proporcionan demasiada abstracción sobre SQL, creando conceptos como "criterios", "predicados", "restricciones" que son conceptos muy buenos, pero no SQL.
La idea general de la abstracción de persistencia en Java parece estar basada en el modelo relacional de objetos, donde RDBMS de alguna manera coincide con el mundo OO. El debate ORM siempre ha sido emotivo, ya que no parece existir una solución única que se adapte a todos, incluso si tal solución puede existir.
jOOQ
Mi preferencia personal de cómo evitar problemas relacionados con ORM es apegarme al mundo relacional. Ahora, la elección del paradigma del modelo de datos no debe ser el tema de discusión, ya que es una preferencia personal o una cuestión de qué modelo de datos se adapta mejor a un problema concreto. La discusión que me gustaría comenzar es sobre mi propia herramienta de persistencia llamada jOOQ . Diseñé jOOQ para proporcionar la mayoría de las ventajas que tienen las herramientas modernas de persistencia:
- Un lenguaje específico de dominio basado en SQL
- Generación de código fuente que asigna el esquema de base de datos subyacente a Java
- Soporte para muchos RDBMS
Agregar algunas características que tienen pocas herramientas modernas de persistencia (corríjame si me equivoco):
- Soporte para SQL complejo: uniones, selecciones anidadas, autouniones, alias, cláusulas de caso, expresiones aritméticas
- Soporte para SQL no estándar: procedimientos almacenados, UDT, ENUMS, funciones nativas, funciones analíticas
Considere la página de documentación para más detalles: http://www.jooq.org/learn.php . Verá que se implementa un enfoque muy similar en Linq para C #, aunque Linq no está diseñado exclusivamente para SQL.
La pregunta
Ahora, habiendo dicho que soy un gran admirador de SQL, me pregunto si otros desarrolladores compartirán mi entusiasmo por jOOQ (o Linq). ¿Es este tipo de enfoque para la abstracción de persistencia viable? ¿Cuáles son las ventajas / desventajas que puede ver? ¿Cómo podría mejorar jOOQ, y lo que falta en tu opinión? ¿Dónde me equivoqué, conceptual o prácticamente?
Respuestas críticas pero constructivas apreciadas
Entiendo que el debate es emocional. Existen muchas herramientas excelentes que ya hacen cosas similares. Lo que me interesa es comentarios críticos pero constructivos, basados en su propia experiencia o artículos que haya leído.
Respuestas:
Creo que está en el camino correcto y debería continuar con su solución. Algunas de las críticas anteriores son demasiado duras, pero se hacen algunos puntos válidos.
Yo también he buscado por mucho tiempo una solución ORM con todas las funciones que se ajuste a mis necesidades, pero cada solución que miré se quedó corta. Cada uno tiene sus pros y sus contras, pero ninguno realmente hizo todo lo que quería. Estoy de acuerdo con su crítica a estas soluciones, es decir, que generalmente son complejas y tienen una curva de aprendizaje pronunciada.
El principal contendiente tendría que ser el estándar de facto, Hibernate. Es completo, robusto y bien probado. Lo respeto y lo aprecio por lo que es. Ahora, a riesgo de ofender a la mitad de la comunidad de programadores, también debo decir que es una pieza hinchada y compleja de código no funcional. He pasado bastante tiempo hurgando en sus entrañas, tratando de depurarlo y comprenderlo, y no me impresionó lo que vi. Dicho esto, aún lo recomendaría como punto de partida para cualquiera que busque un buen ORM. Sobresale en CRUD simple, pero no lo usaría para consultas masivas de rendimiento, como minería de datos o procesamiento de números.
Desafortunadamente, mi aplicación tiene más variedad de números (aunque también hay algunos CRUD), así que decidí lanzar la mía. Sabía desde el principio que sería inferior en comparación con las otras soluciones disponibles, pero sería lo suficientemente bueno y me daría el rendimiento que necesitaba. Ahora esta es la mejor parte: ¡se parece mucho a tu solución!
Esto es lo que creo que hiciste bien: declaraste tus creencias subyacentes como una especie de declaración de misión, y esas creencias son correctas. Obviamente, también he pasado bastante tiempo pensando en este problema, y es difícil de resolver. Pero a medida que pasa el tiempo, creo que la comunidad de programación llega a comprenderlo mejor y crearemos mejores soluciones. Felicitaciones a todos los esfuerzos anteriores (especialmente Hibernate), pero creo que podemos hacerlo mejor.
Su solución refina mejor el problema, pero solo resuelve parte de él. Creo que un enfoque en capas puede darnos todo lo que queremos. Lo que se te ocurrió / IMO, es la capa base. Como ha sugerido, creo que esta capa se genera mejor automáticamente en función de un esquema de base de datos. Debe ser un modelo de objeto relacional muy simple que se asigne directamente a la base de datos y no más. Tiene razón en que los datos persisten mucho más que el código, por lo que a este nivel, los datos deberían generar código y no al revés. Soportaría CRUD así como consultas masivas de alto rendimiento. Probablemente implementaría algún tipo de caché L1 en esta capa.
Sin embargo, lo que destaca en otras soluciones ORM es la capacidad de definir sus objetos de una manera que no dependa tanto de la estructura real de la base de datos subyacente. Para esta funcionalidad, crearía otra capa. Por necesidad, esta capa se vuelve más abstracta, ojalá sea más simple (a expensas de la funcionalidad perdida), y se basa en la capa anterior. Podría utilizar un caché L2.
Estoy abierto a tener más capas, pero el punto clave para mí es que al proporcionar múltiples puntos de entrada a la biblioteca, puede satisfacer todas las necesidades. Para aquellos que desean una solución CRUD simple que se asigne directamente a los objetos de su elección, pueden construir en la capa superior. Para aquellos que buscan algo más potente y eficiente pero que desean incurrir en la complejidad adicional, pueden conectarse a la capa inferior. No crearía un lenguaje de consulta especial, sino que expondría su objeto generador de consultas para este propósito. Y dado que el código está en capas, esa funcionalidad existe naturalmente sin un paso especial.
Creo que entiendes el espacio y no estás reinventando la rueda, sino que has alcanzado un nicho ligeramente diferente. Y, francamente, esta es una rueda que podría mejorar de todos modos. Te enfrentas a una batalla cuesta arriba compitiendo contra las potencias del pasado, pero si tu solución es buena, y creo que se dirige hacia ese lado, entonces ganará popularidad por sus propios méritos.
fuente
"Hay muchas balas mágicas por ahí, y no faltan desarrolladores ingenuos".
Sin ofender, parece que no comprende completamente lo que se ha hecho en este espacio y, por lo tanto, está reinventando algunas ruedas: la experiencia nos dirá a todos que las ruedas que inventa, aunque ordenadas y divertidas, es probable que no sean tan bueno o útil como las ruedas bien refinadas ya disponibles.
fuente
Un escenario que haría que este tipo de API sea adecuado es cuando necesita un generador de SQL independiente de la base de datos que la mayoría de los ORM no le permiten tener. Una gran situación donde la he necesitado es generar informes. He necesitado construir SQL de una manera orientada a objetos y ejecutar este sql en varias bases de datos para probar. Hibernate y otros ORM dependen mucho de las configuraciones, lo que limita mi construcción sql de modo que no puedo combinar la tabla donde no existe asociación en los xmls. Como cualquier asociación es posible en el Módulo de informe que estoy desarrollando, he buscado algo diferente. Entonces me encontré con JOOQ. Simplemente resuelve mi problema. Acabo de necesitar un acceso de solo lectura, nunca encuentro problemas de depuración dolorosos como en hibernación.
De hecho, estoy planeando desarrollar una forma diferente de modelar datos en lugar de la forma POJO común y usar JOOQ como una de las bases, que es una capa para construir SQL. Entonces, además de JOOQ, planeo crear una forma más flexible de modelar datos / entidades usando HashMaps. Mi diseño permitiría integrar el diseño de front-end y back-end más fácilmente en un punto de entrada, aunque usaría varias capas para completar el marco, tal como lo han dicho los comentarios anteriores. JOOQ realmente jugará un papel muy bueno como en mi propio proyecto, sirve como una de las bases o pilares.
Así que sigan con el buen trabajo lukas!
fuente
Si entiendo su herramienta correctamente, asigna Objetos directamente a un marco conceptual de SQL en lugar de asignar Objetos que implementan alguna asignación a la funcionalidad SQL (ORM), casi como una abstracción ORM: para un mayor control geek para que pueda usar más funciones SQL ORM generalmente no te daría?
No estoy seguro de qué problema estás tratando de resolver. Dado que su herramienta requiere un conocimiento profundo de SQL, ¿la gente no usaría, bueno, SQL? ¿Es el código de pegamento del que estás tratando de deshacerte? ¿Mejor validación de las consultas SQL a través del modelado API en lugar de cadenas simples?
Tengo que admitir que sus ejemplos JOOQ se parecen a las versiones LISP del SQL. No es que sea algo malo :) y veo que algunas de las cosas avanzadas son interesantes, pero las ventajas que enumera desaparecen lentamente a medida que avanza cada vez más (más configuración, menos abstracto, más arraigado en el santuario interno del SQL específico motor, etc.)
Una sugerencia que me gustaría ver que echo de menos en la mayoría de los ORM es un marco que puede tratar con Objetos de una manera no relacional, traduciendo las interacciones de Objetos en cualquiera que sea el back-end (SQL, NoSQL, Topic Maps, RDF, etc. .) que requiere el almacenamiento en caché del Modelo utilizado en lugar de los detalles de las interacciones SQL, dialectos y pensamiento relacional.
En mi humilde opinión, por supuesto. :)
fuente