jOOQのJavaジェネレータを使ってみる

2019年7月1日

jOOQまとめがあるので参照されたい

jOOQとは何かで書いたように、(必ずしも必要ではないのだが)jOOQでのSQL生成の前提として、対象とするデータベースのテーブル名、フィールド名等の情報からのJava用ソースを生成しておく。

これを行うためのツールがjOOQにビルトインされているので、これを使ってみる。対象はMySQLデータベースだ。

ジェネレータの実行

必要なライブラリ

gradleの場合には、以下の依存を指定する。

dependencies {  
  compile group: 'org.jooq', name: 'jooq', version: '3.11.11'
  compile group: 'org.jooq', name: 'jooq-codegen', version: '3.11.11'
  compile group: 'org.jooq', name: 'jooq-meta', version: '3.11.11'
  compile 'mysql:mysql-connector-java:5.1.21'
}

設定ファイル

以下のようなxmlファイルを作成する。仮にconfig.xmlとする。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.11.0.xsd">
  <!-- MySQLデータベース接続情報 -->
  <jdbc>
    <driver>com.mysql.jdbc.Driver</driver>
    <url>jdbc:mysql://localhost:3306</url>
    <user>root</user>
    <password>パスワード</password>
  </jdbc>

  <generator>
    <!--  Java用のコードジェネレータを指定。他にScala用等がある -->
    <name>org.jooq.codegen.JavaGenerator</name>

    <database>
      <!-- データベースタイプ -->
      <name>org.jooq.meta.mysql.MySQLDatabase</name>

      <!-- データベース名 -->
      <inputSchema>cm55lic</inputSchema>

      <!-- データベース中のすべてを取得する指定 -->
      <includes>.*</includes>

      <!-- データベースから除外する指定 -->
      <excludes></excludes>
    </database>

    <target>
      <!-- 生成コードのパッケージ名称 -->
      <packageName>cm55lic.generated</packageName>

      <!-- 生成コードの置き場所 -->
      <directory>C:/users/admin/desktop/generated</directory>
    </target>
  </generator>
</configuration>

実行

上記のライブラリをクラスパスに指定して実行しても良いのだがが、Eclipse等の環境では以下のプログラムで十分だ。args[0]に”config.xml”を指定する。

  public static void main(String[]args) throws Exception {
    org.jooq.codegen.GenerationTool.main(args);    
  }

※データベースが見つからないとか、接続できない場合には以下のエラーメッセージが表示され、何も生成されない。

警告: No schemata were loaded  : Please check your connection settings, and whether your database (and your database version!) is really supported by jOOQ. Also, check the case-sensitivity in your configured <inputSchema/> elements : {=[mydatabase]}

生成されたJavaソースとその使い方

このJavaソースを利用してjOOQを使ってみる。

import java.sql.*;

import org.jooq.*;
import org.jooq.impl.*;

import cm55lic.generated.tables.records.*;

// これが重要、テーブル名(TBL_ADMIN)をプリフィックス無しで記述する。
import static cm55lic.generated.Tables.*;

public class Main {

  public static void main(String[]args) throws Exception {
    String userName = "root";
    String password = "パスワード";
    String url = "jdbc:mysql://localhost:3306/cm55lic";

    try (Connection conn = DriverManager.getConnection(url, userName, password)) {
      DSLContext create = DSL.using(conn, SQLDialect.MYSQL);          
      create.selectFrom(TBL_ADMIN).fetch().forEach(System.out::println);
      /* 上記と同じ、Java8以前
      Result<TblAdminRecord>recs = create.selectFrom(TBL_ADMIN).fetch();     
      for (TblAdminRecord rec: recs) {
        System.out.println("" + rec);
      }     
      */
    }   
  }
}

出力結果は以下のようになる。

+------+------------------+--------------------------------------------------+
|adm_id|adm_email         |adm_password                                      |
+------+------------------+--------------------------------------------------+
|     1|.........@cm55.com|$2a$10$e.nLbL/MfK7UJQbi...........................|
+------+------------------+--------------------------------------------------+

+------+-------------+--------------------------------------------------+
|adm_id|adm_email    |adm_password                                      |
+------+-------------+--------------------------------------------------+
|     2|....@cm55.com|$2a$10$YC1UptH3wdUKIZ4qhXHOhe.....................|
+------+-------------+--------------------------------------------------+

型安全が確保されている

コメントで示したJava8以前の部分だが、

 Result<TblAdminRecord>recs = create.selectFrom(TBL_ADMIN).fetch()

TBL_ADMINを指定すると、専用のTblAdminRecordクラスでしか受け取れなくなる。別のテーブル用のレコードクラスは使えなくなるのだ。ここでも型安全が確保されている。