jOOQ : Faire du SQL en JAVA

Le framework jOOQ (Java Object Oriented Querying) permet de réaliser simplement des requêtes SQL en JAVA, et supportant les principaux SGBD (Postgres, MySQL, Oracle, H2...)

jOOQ repose sur un système de génération de code afin de créer les classes correspondant aux tables présentes en base. Afin d'en bénéficier il suffit d'ajouter le plugin jooq-codegen dans le pom.xml et d’exécuter le goal maven generate-sources.

(Ici un exemple avec une base Postgres)

<profile>
       	<id>jooq-codegen</id>
	       	<build>
	       		<plugins>
	       			<plugin>
						<groupId>org.jooq</groupId>
						<artifactId>jooq-codegen-maven</artifactId>
						 <executions><execution><phase>generate-sources</phase><goals><goal>generate</goal></goals></execution></executions>
						<dependencies>
							<dependency>
								<groupId>org.postgresql</groupId>
								<artifactId>postgresql</artifactId>
								<version>${postgresql.version}</version>
							</dependency>
						</dependencies>                 
						<configuration>                   
							<jdbc>
								<driver>org.postgresql.Driver</driver>
								<url>jdbc:postgresql://localhost:5433/my_db</url>
								<user>db_user</user>
								<password>db_password</password>
							</jdbc>                                         
							<generator>
								<database>
									<name>org.jooq.util.postgres.PostgresDatabase</name>
									<includes>.*</includes>
									<excludes></excludes>
									<inputSchema>my_db_schema</inputSchema>
								</database>
								<target>
									<packageName>com.my.package.jooq</packageName>
									<directory>src/main/java</directory>
								</target>
							</generator>
						</configuration>
					</plugin>
	       		</plugins>
	       	</build>
       </profile>
pom.xml

jOOQ se base sur une instance de la classe DSLContext comme base pour toute action. Pour créer cette instance, on récupère une java.sql.Connection classique et on utilise la méthode DSL.using(Connection connection) pour instancier notre DSLContext.

try (Connection conn = DriverManager.getConnection("localhost:5433/my_db", "db_user", "db_password")) {
	DSLContext context = DSL.using(conn, SQLDialect.POSTGRES);
}catch(Exception E){
	///...
}

Une fois que nous avons notre DSLContext, nous pouvons l'utiliser pour requêter.

Request request = context.select(Tables.MY_TABLE.ID,
								 Tables.MY_TABLE.FIELD_1,
								 Tables.MY_OTHER_TABLE.fields())// La méthode fields() permet de retourner tous les champs de la table
	.from(Tables.MY_TABLE)
	.join(Tables.MY_OTHER_TABLE)
	.onKey()// La méthode onKey() permet de laisser jOOQ déterminer la clef étrangère à laquelle on fait référence.
	.where(Tables.MY_TABLE.FIELD_1.eq(50))//eq() permet de tester une égalité
	.orderBy(Tables.MY_TABLE.FIELD_1.desc())
	.limit(1);

Si jamais une méthode n'est pas supportée nativement par le SGBD cible (comme les clauses LIMIT et OFFSET),  jOOQ émule ces comportements.

 

Une fois que nous avons notre requête, il est temps de l'exécuter. La manière la plus simple est d'appeler la méthode fetch() sur notre requête.

Result<Record> results = request.fetch();

//Récupération du champ my_table.id de la première ligne retournée
results.get(0).getValue(Tables.MY_TABLE.ID);
Execution de la requete

Cependant, il est assez probable que lors de l’exécution de nos requêtes, nous voulions retrouver des objets proches de notre modèle plutôt que d'avoir un Result et de devoir tout parser à la main.

Assumons donc que la classe suivante MyObject mappe notre table MyTable :

@Table("my_table")
public MyObject{
	
	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	@Column
	private String myField_1;
	
	// getters and setters
}
Classe MyObject

Nous pouvons à présent spécifier à jOOQ de récupérer non pas un Result<Record>, mais bien une liste de MyObject :

List<MyObject> results = request.fetchInto(MyObject.class);

Notre programme complet à présent ressemble à ceci :

try (Connection conn = DriverManager.getConnection("localhost:5433/my_db", "db_user", "db_password")) {
	DSLContext context = DSL.using(conn, SQLDialect.POSTGRES);
	
	Request request = context.select(Tables.MY_TABLE.ID,
								 Tables.MY_TABLE.FIELD_1,
								 Tables.MY_OTHER_TABLE.fields())// La méthode fields() permet de retourner tous les champs de la table
	.from(Tables.MY_TABLE)
	.join(Tables.MY_OTHER_TABLE)
	.onKey()// La méthode onKey() permet de laisser jOOQ déterminer la clef étrangère à laquelle on fait référence.
	.where(Tables.MY_TABLE.FIELD_1.eq(50))//eq() permet de tester une égalité
	.orderBy(Tables.MY_TABLE.FIELD_1.desc())
	.limit(1);
	
	List<Tables.MY_TABLE> results = request.fetchInto(MyObject.class);
	
}catch(Exception E){
	///...
}
Programme complet

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.