SqlTemplateっていうJdbcTemplateのラッパーを作ってみました。
「SQLが書きたいんや!」という想いのもと、
Spring Bootと組み合わせて簡単に使える、
JdbcTemplateのラッパーライブラリを勢いで作ってみました。
GitHubに置いています。
https://github.com/cero-t/sqltemplate
JdbcTemplate / NamedParameterJdbcTemplateをベースにして、
1. SQLファイルが使えること
2. Date and Time APIに対応すること
3. publicフィールドに対応すること
4. APIが今風であること
の4つを目的にして作りました。
それならMirageでいいんじゃね? という想いは消えませんが、
Spring標準機能のみを使うことによる、政治的な使いやすさを取りました。
作りましたって言っても、ただのラッパーですので
ソースコードはすっごく小さくて、空行とコメントを入れても600行ぐらいしかありません。
ジェバンニでなくとも一晩でやってくれるぐらいのサイズです。
利用イメージ
exampleのプロジェクトも作っておきました。
https://github.com/cero-t/sqltemplate/tree/master/sqltemplate-example
使う側のソースコードは、こんな感じになります。
@Component public class SampleProcess { @Autowired SqlTemplate query; public void process() { List<Emp> emps = query.forList("sql/selectAll.sql", Emp.class); emps.forEach(e -> System.out.println(e.ename)); Emp emp = query.forObject("sql/selectByEmpno.sql", Emp.class, 7839); System.out.println(emp.ename); Map<String, Object> condition = new HashMap<>(); condition.put("deptno", 30); condition.put("job", "SALESMAN"); emps = query.forList("sql/selectByCondition.sql", Emp.class, condition); emps.forEach(e -> System.out.println(e.ename)); } }
forObjectで1件検索、forListで複数件検索。
第一引数がSQLファイル名で、第二引数が戻り値の型、
第三引数以降がSQLにバインドするパラメータです。
ちなみにIntelliJを使っていると、ファイル名にカーソルをあわせて
Ctrl (Command) + クリックでSQLファイルを開けるのが嬉しいですね。
SQLファイルは、こんな感じになります。
select * from emp inner join dept on emp.deptno = dept.deptno where dept.deptno = :deptno and emp.job = :job
第三引数に指定したMapやEntityの値を、SQLのパラメータとしてバインドします。
内部的にはNamedParameterJdbcTemplateに処理を委譲しているだけです。
名前を指定せずに ? を使うこともできます。
select * from emp where empno = ?
第三引数以降に指定した任意の数の基本型(String、Date、Number)をバインドします。
こちらは内部的にJdbcTemplateに委譲しているだけです。
使い方
使うための設定は一つだけ。
@Configurationアノテーションをつけたクラスに
SqlTemplateを返すメソッドを作り、@Beanアノテーションをつけます。
@Bean SqlTemplate sqlTemplate(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate) { return new SqlTemplate(jdbcTemplate, namedParameterJdbcTemplate); }
この初期化の仕方は [twitter:@making] がpullリクエストで教えてくれました。
ありがとう!
ちなみにSqlTemplateのコンストラクタの第三引数には、
SQLファイルを読み込む際のテンプレートエンジンを指定することができます。
たとえばここで2-way SQLパーサーを指定すれば、
2-way SQLにも対応できるというスンポーです。
現時点でもFreeMarkerを使うことができるようにしているんですが、
一度も動作確認してないので、動くかどうか分かりません。てへぺろ。
いまあるAPI一覧
用意したメソッドの一覧は、以下になります。
<T> T forObject(String fileName, Class<T> clazz, Object... args) <T> T forObject(String fileName, Class<T> clazz, Map<String, Object> params) <T> T forObject(String fileName, Class<T> clazz, Object entity) <T> List<T> forList(String fileName, Class<T> clazz, Object... args) <T> List<T> forList(String fileName, Class<T> clazz, Map<String, Object> params) <T> List<T> forList(String fileName, Class<T> clazz, Object entity) int update(String fileName, Map<String, Object> params) int update(String fileName, Object entity) int update(String fileName, Object... args)
戻り値をMapにする「forMap」とか
実案件では欠かせない「batchUpdate」は、まだ作っていません。
委譲するだけなので、作っちゃえばいいんですけどね。
制限事項的なやつ
とりあえずコンセプト実証した程度なので、色々できません。
1. 上に書いた通り、forMapとbatchUpdateがありません。
2. JSR-310を使っているので、Java8でしか動きません。
3. publicフィールドのないgetter/setterベースのJavaBeansは使えません。
4. パッケージ名が変です。
5. mvnリポジトリに置いてないです。
6. README.mdちゃんと書け。
ひとまずは「こんなコンセプトでサクッとできたよ! 」っていう位置づけです。
ご自由に参考にしてください!