Spring Boot で jOOQ を触ってみた
JOOQ とは ORマッパーの一種なのか難しいところですが、一般的なORマッパーを利用するよりは生のDSLの記述に近くわかりやすく書けるのが jOOQ になります。
Spring Boot と 前回の Flyway を紹介した際のテーブル情報を利用して、セットアップと簡単なデータ取り出しのみを紹介したいと思います。
まず、雛形を作成します。
SpringBoot では、starter プロジェクトで jOOQがサポートされています ので、今回はこちらを利用したいと思います。
# curl https://start.spring.io/starter.tgz -d dependencies=web,jooq -d bootVersion=2.0.0.M7 -d baseDir=jooq -d artifactId=jooq | tar -xzvf -
今回は、作成済みのテーブルから jOOQ に対応した Java のソースコードを作成します。
作成済みのテーブル以外に、CREATE TABLE などのDDL、またJPAから jOOQ に対応した Java のソースコードも作成できます。
(移行する時などが楽そうですね)
pom.xml の plugin に下記内容を記述します。
org.jooq
jooq-codegen-maven
generate-mysql
generate-resources
generate
${driverName}
${url}
${user}
${password}
org.jooq.util.mysql.MySQLDatabase
.*
true
jooq
com.example.jooq.db.mysql
src/main/java
実際に、動かしてみましょう。
#mvn generate-resources
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@
@@@@@@@@@@@@@@@@ @@ @@ @@@@@@@@@@
@@@@@@@@@@ @@@@ @@ @@ @@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@ @@ @@ @@@@ @@@@@@@@@@
@@@@@@@@@@ @@ @@ @@@@ @@@@@@@@@@
@@@@@@@@@@ @@ @ @ @@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Thank you for using jOOQ 3.10.1
[INFO] ARRAYs fetched : 0 (0 included, 0 excluded)
[INFO] Enums fetched : 0 (0 included, 0 excluded)
[INFO] Packages fetched : 0 (0 included, 0 excluded)
[INFO] Routines fetched : 0 (0 included, 0 excluded)
[INFO] Tables fetched : 1 (1 included, 0 excluded)
[INFO] No schema version is applied for catalog . Regenerating.
[INFO]
[INFO] Generating catalog : DefaultCatalog.java
[INFO] ==========================================================
[INFO] Generating schemata : Total: 1
[INFO] No schema version is applied for schema jooq. Regenerating.
[INFO] Generating schema : Jooq.java
[INFO] ----------------------------------------------------------
[INFO] Sequences fetched : 0 (0 included, 0 excluded)
[INFO] UDTs fetched : 0 (0 included, 0 excluded)
[INFO] Generating tables
[INFO] Synthetic primary keys : 0 (0 included, 0 excluded)
[INFO] Overriding primary keys : 1 (0 included, 1 excluded)
[INFO] Generating table : Products.java [input=products, output=products, pk=KEY_products_PRIMARY]
[INFO] Indexes fetched : 1 (1 included, 0 excluded)
[INFO] Tables generated : Total: 650.671ms
[INFO] Generating table references
[INFO] Table refs generated : Total: 652.212ms, +1.541ms
[INFO] Generating Keys
[INFO] Keys generated : Total: 654.786ms, +2.573ms
[INFO] Generating Indexes
[INFO] Indexes generated : Total: 656.758ms, +1.971ms
[INFO] Generating table records
[INFO] Generating record : ProductsRecord.java
[INFO] Table records generated : Total: 666.649ms, +9.891ms
[INFO] Domains fetched : 0 (0 included, 0 excluded)
[INFO] Generation finished: jooq: Total: 666.868ms, +0.219ms
[INFO]
[INFO] Removing excess files
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.939 s
[INFO] Finished at: time
[INFO] Final Memory: 22M/308M
[INFO] ------------------------------------------------------------------------
下記のようにjOOQを利用するためのソースコードが生成されます。
├── java
│ └── com
│ └── example
│ └── jooq
│ └── db
│ └── mysql
│ ├── DefaultCatalog.java
│ ├── Indexes.java
│ ├── Jooq.java
│ ├── Keys.java
│ ├── Tables.java
│ └── tables
│ ├── Products.java
│ └── records
│ └── ProductsRecord.java
pom.xml で指定した場所にソースコードが吐き出されています。
実際に吐き出されたソースコードを利用して、データを取得したいと思います。
import static com.example.jooq.db.mysql.tables.Products.PRODUCTS;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;;
@Controller
public class SampleController {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private DSLContext dsl;
@ResponseBody
@RequestMapping(value="/sample", method=RequestMethod.GET)
public String sample() {
Result result = dsl.select()
.from(PRODUCTS)
.fetch();
if (result.isEmpty()) {
return "failed";
}
for (Record r : result) {
logger.info("id : {} product name : {}", r.getValue(PRODUCTS.ID), r.getValue(PRODUCTS.NAME));
}
return "success";
}
}
実行結果は下記になります。
2018-01-10 18:12:53.370 INFO 55836 --- [nio-8080-exec-1] c.e.jooq.controller.SampleController : id : 1 product name : 商品A
2018-01-10 18:12:53.370 INFO 55836 --- [nio-8080-exec-1] c.e.jooq.controller.SampleController : id : 2 product name : 商品B
2018-01-10 18:12:53.370 INFO 55836 --- [nio-8080-exec-1] c.e.jooq.controller.SampleController : id : 3 product name : 商品C
個人的は、fetch などの名前がわかりやすいかなと思っております。
もう少し複雑なテーブルを用意して実際のソースコードの変換など、次回でご紹介できればと思います。
そして、サンプルコードが、Spring Boot や jOOQ で用意されていますので、ぜひ利用してみてください。