続:Apache Wicketを使ってみる -データアクセス編-
0. データアクセスをどうするか
Quick Start Wizardで作成したMavenプロジェクトには、当然のことながらデータアクセスに関するライブラリがないので、自力でどうにかするしかない。
とはいえ、Spring Bootのような至れり尽くせりな環境でもないけど、ローレベルなJDBCをスクラッチで書き起こす元気もないので、今回はsql2oというライブラリを使ってみることにする。
1. sql2oとは
sql2o本家、およびGitHubの記述をざっくりまとめると、こんな感じ。
位置づけ的にはDapper.NETやRoom Persisitence Libraryに近いかも。
- 小さく軽量なデータアクセス用ライブラリ
- JDBCのResultSetをPOJOに変換する機能を提供するが、SQLを生成する機能はない
- 他の著名なライブラリに比べ、高速に(モノによっては6,7倍高速)動作する
導入はMavenで。執筆時点の最新版は1.6.0だった。
今回はDBMSにMySQLを使ってみることにするので、Connector/Jも一緒に設定しておく。
<dependency>
<groupId>org.sql2o</groupId>
<artifactId>sql2o</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
2. 検索系処理
データベースへの接続は、Sql2oのコンストラクタに接続文字列を渡すことで作ってくれる。
なお、あえてすべてKotlinで書いてみた。
val database: Sql2o = Sql2o("jdbc:mysql://localhost:3306/mydb", "mydbadmin", "mydbadmin")
オープン処理とかは、DAOの基底クラスにプロパティを書いておくと扱いやすいかも。
/** トランザクションなしのConnection */
val connection: Connection
get() {
return database.open()
}
/** トランザクション開始ありのConnection */
val connectionWithTran: Connection
get() {
database.beginTransaction()
}
で、検索系はSQLをそのまま書き、それを Connection#createQuery(String) に渡して Query オブジェクトを作り、 Query#executeAndFetch(Class) を実行すると ResultSet を POJO へバインドしてくれる。
// SQLをそのまま書く。長いSQLの場合はヒアドキュメントを使うと楽かも
val sql = "select todo_id, todo_title, created_at, finished from todo"
// 接続をオープン
val conn = connection
try {
// use 関数でクエリ実行(Javaでいうところのtry-with-resources)
conn.use {
// setAutoDeriveColumnNames はスネークケース→キャメルケースを自動変換する設定
val query = conn.createQuery(sql).setAutoDeriveColumnNames(true)
val ret: MutableList<ToDo> = query.executeAndFetch(ToDo::class.java)
}
} catch (e: Exception) {
// do something...
}
3. 更新系処理
更新系処理も、検索系処理同様 createQuery(String) でプリペアードステートメントを作り、 Connection#executeUpdate() で実行する。
val sql = "insert into todo (todo_title, created_at, finished) values (:todoTitle, :createdAt, :finished)"
// トランザクション開始ありのConnectionを取得
val tran = connectionWithTran
try {
tran.use {
val stmt = tran.createQuery(sql)
// プリペアードステートメントへバインドするパラメータを追加していく
.addParameter("todoTitle", todo.todoTitle)
.addParameter("createdAt", todo.createdAt)
.addParameter("finished", todo.finished)
stmt.executeUpdate()
// use 関数内で commit()を発行
tran.commit()
}
} catch (e: Exception) {
// do something...
// ロールバックは暗黙的に行われる
}
なお、sql2oには宣言的トランザクションはないので、トランザクション制御は自分でやらなければならない。
4. 最後に
自力でSQLのチューニングをしたほうが手っ取り早い場合なんかには、こういうライブラリのほうがいいかもしれない。
| 固定リンク
コメント