Obtener datos de múltiples tablas con jOOQ

Publicado por pico.dev el , actualizado el .
blog-stack java planeta-codigo programacion
Comentarios

jOOQ no proporciona la misma transparencia de acceso a una base de datos relacional que un ORM. Para validar los datos podemos usar Spring Validation y para obtener datos de múltiples tablas lo que comento en este artículo. Usando jOOQ podemos exprimir todo el potencial del lenguaje SQL, comprobación de tipos por el compilador de argumentos y resultados, usar la base de datos como única fuente de la verdad, diferentes formas de acceso a la base de datos usando el patrón Active Record, directamente SQL, …

Java

Una de las facilidades que proporciona la librería de persistencia Hibernate usada ampliamente en aplicaciones Java como buen ORM es la navegación de las relaciones a través de los métodos del modelo de objetos de forma transparente a las consultas SQL que se necesiten lanzar a la base de datos para ir obteniendo los resultados. Sin embargo, pensar únicamente en este modelo orientado a objetos o abusar de él sin tener en cuenta el número de consultas SQL que estamos realizando al modelo relacional provocará que la aplicación sea lenta, poco eficiente y sobrecargue el servidor de base de datos. Como ejemplo usando un ORM es habitual provocar un problema de N+1 o 1+N que deberemos detectar y corregir.

Por el contrario jOOQ se postula como alternativa a Hibernate para proporcionar persistencia en base de datos relacionales. Se basa en proporcionar un acceso usando un DSL más cercano al lenguaje SQL de la base de datos en vez de proporcionar una capa de abstracción para el modelo de objetos, la forma de acceder a la base de datos es muy flexible pudiéndose emplear para generar consultas SQL en forma de String que lanzaremos con JDBC o con la clase JdbcTemplate de Spring. Las SQL son construidas con una API en forma deDSL o usando el patrón ActiveRecord con la posibilidad de que el compilador realice la validación de tipos tanto para los parámetros como para los resultados.

Sin embargo, aunque jOOQ permite también navegar las relaciones entre las entidades implementadas con el patrón ActiveRecord puede sucedernos que se nos presente el mismo problema 1+N de Hibernate si por ejemplo obtenemos una lista departamentos con 1 SQL y posteriormente 1 consulta más para obtener los empleados según se itera cada departamento en un bucle, en total 1+N consultas para los departamentos y sus empleados. Como sería el siguiente caso.

Si sabemos que vamos a necesitar una entidad y las relacionadas, como en un departamento y sus empleados, es mejor obtener todos los datos en una única consulta. Una de las formas en que jOOQ devuelve resultados es a través de objetos Record que representa a los datos de resultado de la SQL, por otro lado jOOQ genera un objeto Record por cada tabla de la base de datos. Si en una consulta necesitamos únicamente los datos de una tabla podemos obtener los datos en el ActiveRecord que jOOQ genera para esa tabla. Si queremos obtener datos de múltiples tablas deberemos emplear otra forma, por ejemplo, podemos recoger los resultados en un objeto de tipo Record genérico y posteriormente extraer los datos a los diferentes Record concretos de la aplicación.

El objeto RecordContainer es el siguiente, con una propiedad por cada posible Record que pudiese recuperar. Solo necesitaremos crear uno que incluya una propiedad con todos los posibles Record que necesitemos.

Las clases completas Main.java y AppServiceImpl.java son las siguientes.

La salida en la terminal de esta aplicación al iniciarse es la siguiente:

jOOQ presenta varias cosas interesantes sobre Hibernate, ya es en una alternativa con un enfoque diferente, con ideas interesantes, algunas ventajas y el tiempo dirá si se convierte en el nuevo estándar para la persistencia en las aplicaciones Java. Otra de las cosas comunes que necesitaremos en una aplicación es validar los objetos Record, una posibilidad es usando Spring Validation.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew updateDatabase && ./gradlew generateModels && ./gradlew run.

Yo apoyo al software libre