※アウトプット用メモですので他記事と被っている箇所があるかもしれません。悪しからず。
#Doma2とは
データベースアクセスに使います。特徴としては以下。
公式(https://doma.readthedocs.io/en/stable/)によると
Doma 2は、Java 8以降用のデータベースアクセスフレームワークです。Domaにはさまざまな長所があります。
・注釈処理を使用してコンパイル時にソースコードを検証して生成します。
・データベース列をユーザー定義のJavaオブジェクトにマップします。
・「2-way SQL」と呼ばれるSQLテンプレートを使用します。
・java.time.LocalDate、 java.util.Optionalおよびjava.util.stream.StreamなどJava 8で導入されたクラスをサポート
・他のライブラリに依存しない
ほとんど翻訳のままですので少し日本語がおかしいかもしれません。。。
大きな利点としては以下の2点であるかと
・JRE 以外のライブラリへの依存が一切ない(依存性には敏感ですww)
・SQLをファイルですべて管理できる(疎結合ってやつですかね?)
これは自分が使ってみた意見ですが、SQLファイルで管理することで過剰な共通化を防ぐ利点があると思いました。
共通化のしすぎは逆にわかりにくくなることがあります。
##実装
公式にサンプルプロジェクトがありましたのでこちらがわかりやすいかと思います。
公式サンプル
主に必要な構成としては
・Dao (Daoはデータベースアクセスのためのインタフェース)
・Entity (テーブルを表現する(だけではないですが)クラス)
・SQLファイル (クエリー)
になります。
DaoでCRUD処理をするメソッドを定義します。
package com.example.dao;
import com.example.entity.MstEmployee;
import com.example.entity.UserEntity;
import org.seasar.doma.Dao;
import org.seasar.doma.Insert;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/** 従業員マスタのDaoインターフェース. */
@ConfigAutowireable
@Dao
public interface MstEmployeeDao {
@Select
List<MstEmployee> selectAll();
@Select
MstEmployee selectOne(String id);
@Select
UserEntity selectUser(String id);
@Insert
@Transactional
int insert(MstEmployee mstEmployee);
}
このメソッドでやりたい問い合わせをSQLファイルにしてやろう。という使い方です。SQLファイルを配置する場所はMETA-INF
の中に上記クラス内のpackage com.example.dao;
と同じようにフォルダ階層を作成しかつファイル名をメソッド名と同じ名前にします(拡張子はsql)
サンプルプロジェクトのtreeを見るとわかりやすいと思います。
├── pom.xml ... Maven設定ファイル
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ ├── App.java ... アプリケーション実行ファイル
│ │ ├── SecurityConfig.java ... セキュリティ設定ファイル
│ │ ├── dao ... Doma2のDAOクラス格納パッケージ
│ │ │ ├── MstEmployeeDao.java
│ │ │ ├── MstNewsDao.java
│ │ │ └── MstRoleDao.java
│ │ ├── dto
│ │ │ └── NewsDto.java
│ │ ├── entity ... Doma2のEntityクラス格納パッケージ
│ │ │ ├── AuditEntity.java
│ │ │ ├── MstEmployee.java
│ │ │ ├── MstNews.java
│ │ │ ├── MstRole.java
│ │ │ ├── UserEntity.java
│ │ │ └── listener
│ │ │ └── AuditListener.java
│ │ ├── security ... Spring Securityの認証機能
│ │ │ ├── LoginUserDetails.java
│ │ │ ├── LoginUserDetailsService.java
│ │ │ └── UserInfo.java
│ │ ├── service ... サービスクラス格納パッケージ
│ │ │ ├── NewsService.java
│ │ │ └── NewsServiceImpl.java
│ │ └── web ... Spring MVC コントローラクラス格納パッケージ
│ │ ├── LoginController.java
│ │ ├── NewsController.java
│ │ ├── TopController.java
│ │ └── manager
│ │ ├── NewsForm.java
│ │ ├── NewsManagerEditController.java
│ │ ├── NewsManagerListController.java
│ │ └── NewsManagerRegisterController.java
│ └── resources
│ ├── META-INF
│ │ └── com
│ │ └── example
│ │ └── dao ... Doma2のSQLファイル格納パッケージ
│ │ ├── MstEmployeeDao
│ │ │ ├── selectAll.sql
│ │ │ ├── selectOne.sql
│ │ │ └── selectUser.sql
│ │ ├── MstNewsDao
│ │ │ ├── selectAll.sql
│ │ │ ├── selectNewsDtoByCond.sql
│ │ │ └── selectOneNewsDto.sql
│ │ └── MstRoleDao
│ │ └── selectAll.sql
│ ├── ValidationMessages.properties ... バリデーションチェックのメッセージ設定ファイル
│ ├── application.yml ... アプリケーション設定ファイル
│ ├── data.sql ... 起動時に実行するDDL文
│ ├── messages.properties ... バリデーションチェックメッセージのFormプロパティ置換設定ファイル
│ ├── schema.sql ... 起動時に実行するDML文
│ ├── static ... 実行時にはコンテキストルート直下になる静的ファイル格納フォルダ
│ │ ├── css
│ │ │ └── lib ... CSSライブラリ格納フォルダ
│ │ │ ├── bootstrap-theme.min.css
│ │ │ └── bootstrap.min.css
│ │ ├── fonts ... フォント格納フォルダ(Bootstrap)
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ ├── js
│ │ │ └── lib ... JavaScriptライブラリ格納フォルダ
│ │ │ └── bootstrap.min.js
│ │ └── movie
│ │ ├── sample
│ │ │ └── nc144421.mp4
│ │ └── thumbnail
│ │ ├── nc144421.jpg
│ │ └── nc144555.jpg
│ └── templates ... Thymeleafテンプレート格納フォルダ
│ ├── learning
│ │ └── learning.html
│ ├── loginForm.html
│ ├── manager
│ │ ├── managerLayout.html
│ │ └── news
│ │ ├── edit
│ │ │ ├── newsEditComplete.html
│ │ │ ├── newsEditConfirm.html
│ │ │ └── newsEditInput.html
│ │ ├── list
│ │ │ └── newsList.html
│ │ └── register
│ │ ├── newsRegisterComplete.html
│ │ ├── newsRegisterConfirm.html
│ │ └── newsRegisterInput.html
│ ├── news
│ │ └── news.html
│ └── top
│ └── top.html
└── test ... テストコード格納フォルダ
└── java
└── com
└── example
└── service
└── NewsServiceImplTest.java
##パラメータの書き方
以下のようにsqlファイルを記述することでDaoクラスの変数とsqlファイルの変数をバインドすることができます。
SELECT
employee_id,
employee_last_name,
employee_first_name,
role_id
FROM mst_employee
WHERE
employee_id = /* id */'employee_id';
さらに、以下のように記述することで動的条件を表現できます。
if文とか、アノテーションが使えるんですね。
select
n.mst_news_id id,
n.role_id role_id,
r.role_name role_nm,
n.subject subject,
n.url url,
n.version version
FROM
mst_news n
INNER JOIN
mst_role r
ON
n.role_id = r.role_id
WHERE
/*%if @isNotEmpty(url) */
n.url LIKE /* @prefix(url) */'http'
/*%end*/
/*%if @isNotEmpty(subject) */
AND
n.subject LIKE /* @prefix(subject) */'今日'
/*%end*/
/*%if @isNotEmpty(roleId) */
AND
n.role_id = /* roleId */'01'
/*%end*/
ORDER BY
n.mst_news_id
Spring bootのデータベースアクセスではJPAを使っていましたが、こっちの方が標準みたいですね。