はじめに
今回はspring bootで作成したAPIとデータベースを連携する際に、
ORマッパーとしてjOOQを利用するという想定で、
jOOQの導入、自動生成、簡単な使い方、ついでにちょっとしたポイントなどなどまとめてみました。
ORマッパーやjOOQ導入を検討されている方の参考になればと思います。
jOOQとは
僕が解説しなくても、、、
既にいい感じにまとめて下さっている方がいっぱいいるので、
まずはこの辺りの記事を参考にしてみてください!!
一応解説すると、
spring bootで作成したAPIからOracle、postgreSQL、SQL Serverなどの
データベースへ接続(ユーザ登録、検索、更新とかとか)が必要になるケースを想定した場合、
データベース接続するためのライブラリ利用して(jOOQなどのORマッパーを利用しない場合)
こんな感じでデータを取得することになります。
>>JDBCのお約束と書き方例(入力を受け取ってSQLを実行する例)
別にこれでも動くし、問題はないのですが、
jOOQを導入することでこれらのメリットがあります。
流したいクエリと直感的に同じようにjavaの世界でクエリが組める
例えばここ
String qry = "SELECT * FROM テーブル名 where 列名 = ? AND 列名 = ?";
・
・
ps.setString(1, 入力1);
クエリの側だけ文字列で作って後からwhereの条件を文字列ではめ込んでそれらセットでクエリが完成するのではなく、
jOOQを使うと直感的にSQLっぽくこんな感じで書けたりします。
select USER_NAME from USER_DETAIL where USER_ID = 1
create.select(USER_DETAIL.USER_NAME).from(USER_DETAIL).where(USER_DETAIL.USER_ID,1)
ORマッパーを利用しない場合、
クエリの側を文字列で作ると本物のwhere句をはめ込んだ
最終的なクエリとは少し違うので、複雑なクエリになると読み辛かったり、
ただの文字列なのでIDE(IntelliJとかEclipseとか)の静的解析でバグ検知できず、
プログラムを実行しないとバグが検知できないことが多い。
それに対して、
jOOQ(などのORマッパー)を利用するとクエリをjavaの世界のオブジェクトを利用して実行できるので、
クエリにミスがあるとIDEが静的解析で教えてくれてバグ検知が早いことが多いです。
後、これは実際に使ってみた個人的は感想ですが、
他のORマッパー(HibernateやMyBatis、DBFlute)と比べても
jOOQは流したいクエリに近い記述ができ、
そのおかげで、
クエリでかける事はjOOQでも書けるし、複雑なクエリでも読みやすいです。
クエリ取得結果をjavaの世界で簡単に扱える
例えばここ
while(rs.next()){
String 列名1 = rs.getString("列名1");
Int 列名2 = rs.getInt("列名");
クエリでselectした結果がrsに入っていて、それを自分で文字列として取り出してjavaの世界に持ってきて、数値として取り出してjavaの世界に持ってきて・・・
とするところを、jOOQを利用すると、
Result<UserDetailRecord> result = create.selectFrom(USER_DETAIL).fetch();
こんな感じで書けます。
クエリを実行するとUserDetailRecordというjavaの世界のオブジェクトに取得結果が入ってくれるので扱いやすいです。
jOOQの例で出しているUSER_DETAIL(テーブル)、USER_DETAIL.USER_NAME(カラム)、UserDetailRecordは、
DBから自動生成したJavaの世界でテーブル、カラムを表すクラスです。自動生成の具体的なやり方については後述します。
データベースのある断面から自動生成をする事で、
その断面でのテーブル、レコード、カラムをjavaの世界で表現するクラスが作成でき、
それらを利用してデータベースとやり取りすることで、
データベースの世界をjavaの世界で表現できるようになるため簡単にjavaでテーブル操作できます。
ORマッパーの一番のメリットはそこにあります。(インピーダンスミスマッチの解決)
jOOQの導入!!spring bootとjOOQでpostgreSQLと連携するための準備
jOOQを導入する際のポイントについて解説します。
ソースコードは>>githubに公開しているので動作確認する場合は落として利用してください。
動作確認する場合、
ローカル環境でdocker上にpostgreSQLを構築する前提なので、
Docker Desktopのセットアップが必要になります。
セットアップが完了したら、プロジェクト直下で以下コマンドでpostgreSQLを起動し、
docker-compose up -d
flywayプロジェクト直下で以下コマンドでテスト用データを投入することで事前準備完了です
./mvnw clean install
./mvnw flyway:clean flyway:migrate
flyway周りの詳細は以下にまとめてあるので興味があれば参照ください!!
flywayでテストデータ投入|spring bootで作成したAPIのテストコードのためのデータ準備
それではポイントに絞って解説行きます。
jOOQがDBからJavaのクラスを自動生成するプロジェクトを用意します。
(backendプロジェクトと混在させるとごちゃごちゃするので別にしておくのがオススメ)
jOOQとJDBCライブラリを利用するための設定をjooqプロジェクトとbackendプロジェクトのpomに入れます。
自動生成用の設定(DB接続情報などなど)をjooqプロジェクトのpomに入れます。
backendプロジェクトからjooqプロジェクトで自動生成したクラスを利用できるようにのbackendプロジェクトのpomに依存関係を追加します。
主に依存関係周りの設定と自動生成のための設定が中心でしたがここまでで準備完了です!!
jOOQで自動生成!?spring bootとjOOQでpostgreSQLと連携するための準備
ここからは、
ローカルのdocker上に立ち上げたpostgreSQLと繋いでテーブル、カラムなどに対応したjavaクラスを自動生成していきます。
コマンド一つなので簡単です!!
jooqプロジェクト直下で以下コマンドを実行すれば自動生成されます。
./mvnw jooq-codegen:generate
これだけです。
jOOQの簡単な使い方解説!!spring bootとjOOQでpostgreSQLと連携
ここからは、
jOOQを利用してAPIからテーブルからデータを取得してそのままレスポンス返却していきます。
postgreSQLと繋ぐためのJDBCを利用してデータベースと繋いでこんなクエリをjOOQを利用して投げて取得できた内容をそのままレスポンスとして設定していて
select USER_NAME from USER_DETAIL
データベースが起動していない、接続できない場合はデータベースとの接続に失敗してDB接続エラーみたいな例外をスローするんだな。
くらいのざっくり理解で今回は十分です。
ちなみに事前にセットアップしてあるデータはこんな感じです。(flywayで登録)
動作を確認するには、
backendプロジェクト直下で以下コマンドを実行してAPIを立ち上げます。
./mvnw clean install
./mvnw spring-boot:run
その状態でブラウザからlocalhost:8081/usersへアクセスするとUSER_NAMEに登録してある内容がリストで返却されると思います!!
これはおまけですが、
公開しているソースコードではjOOQのデバックモードにしているので、こんな感じで実際に投げたSQLをログ出力してくれます。
Executing query : select "sample"."user_detail"."user_name" from "sample"."user_detail"
本番環境では負荷が上がるのとログのデータ量が無駄に多くなるのでこの設定はしない方が良いですが、
例えば、
性能が思うように出ないAPIがあって、APIから実行するクエリの改善が必要。
APIから実行しているwhere句の条件などはめ込んだ最終的なクエリは何か??をパッと取得して調査したい。
みたいなときにデバッグモードでログ取得してクエリの解析を進めていきます。
(確か、昔MyBatisを利用していたときには条件まではめ込んだ最終的なクエリまではログ出力できなかった気がする。。。)
すみません、、長くなりました。。。。
まとめ
今回はjOOQについて、利用しない場合との比較を僕なりにしてみたのと、
実際にjOOQを導入、自動生成、使い方について解説しました。
業務でもjOOQを利用していて、
かなりマニアックな使い方をしても今のところどハマりした事はないですし、
他のORマッパーと比較しても個人的にはお気に入りなやつです。
現場での開発を想定した
バックエンドのローカル開発環境構築まとめ記事を作ったので
興味があれば環境構築してアプリ開発の練習をしてみてください!!
IntelliJ IDEA、docker desktop(postgreSQL、keycloak)、Flyway、DBeaverを利用したバックエンド開発環境構築