SQLiteの取扱い
- 基本情報
- データベース接続設定
- データ型マッピング
- 主キーでの自動採番
- ページング検索の条件
- 更新ロックの取得
- プロシージャ
- データベース依存機能
- DBMS独自の注意点
- Exampleのススメ
- DBFlute内部での取扱い
- SQLite補足資料
基本情報
- 対応バージョン
- SQLite 3 以上
- JDBCドライバの同梱
- なし
- (推奨)JDBCドライバ
- sqlite-jdbc-3.6.20.x.jar (Exampleで利用)
DBFluteの SQLite 対応は、(正式サポートではない)準サポートです。
データベース接続設定
データベース接続設定(databaseInfoMap.dfprop)について。
接続設定の仕様 @databaseInfoMap.dfprop
map:{
; driver = org.sqlite.JDBC
; url = jdbc:sqlite:../src/main/resources/[...]/[dbname].db
; schema =
; user = [dbuser]
; password = [dbpassword]
}
- catalog はそもそも対応する概念がないため設定不要
- schema はそもそも対応する概念がないため設定不要
- [xxx]の[]は単なる表現上(ドキュメント上)の囲み
以下、実際のExampleプロジェクトでの設定例です。
e.g. dbflute-sqlite-exampleの場合 {dbname=exampledb} @databaseInfoMap.dfprop
map:{
; driver = org.sqlite.JDBC
; url = jdbc:sqlite:../src/main/resources/exampledb/exampledb.db
; schema =
; user = sa
; password =
}
データ型マッピング
データベース上のデータ型とプログラム型との(デフォルトの)マッピングについて。
- java.lang.String
- TEXT, DATE, DATETIME, (others...)
- java.lang.Integer
- INTEGER
任意のマッピング
ほとんどが String にマッピングされてしまうので、任意の型へのマッピングの調整をお奨めします。例えば、DATE や DATETIME を java.util.Date や java.sql.Timestamp に関連付けると扱いやすくなります。
但し、逆に捉えるとほとんどの型が未サポートのデータ型とも言えますので、未サポートのデータ型に対する取扱いも必ず理解した上でご利用下さい。
主キーでの自動採番
自動採番(連番)の仕組みとして Identity を利用します。
Identity情報はメタデータから取得できるので、設定なしで利用可能です。
ページング検索の条件
limit、offset を利用します。
ConditionBeanのPaging
e.g. ConditionBeanでページング検索 {81-100} @DisplaySql
select ...
from MEMBER dfloc
order by dfloc.MEMBER_NAME asc
offset 80 limit 20
OutsideSqlのManualPaging
e.g. OutsideSqlのManualPagingでページング検索 {81-100} @OutsideSql
/*IF pmb.isPaging()*/
select ...
-- ELSE select count(*)
/*END*/
from ...
where ...
/*IF pmb.isPaging()*/
order by ...
offset /*$pmb.pageStartIndex*/80 limit /*$pmb.fetchSize*/20
/*END*/
- offset や limit ではバインド変数が利用できないので、埋め込み変数("$" を付与)を利用すること
更新ロックの取得
ConditionBean の lockForUpdate() では、for update を利用します。
e.g. ConditionBeanで更新ロックの取得 (cb.lockForUpdate()) @DisplaySql
select ...
from MEMBER dfloc
where ...
and ...
for update
プロシージャ
*未検証
データベース依存機能
データベース依存機能を有効にした場合の利用可能な機能について。
SQLiteに関しては特になし
DBMS独自の注意点
nullsFirst/Last
nulls first/last 構文をサポートしていないため、case when 構文を使って nullsFirst/Last を実現しています。union 句での case when 構文がサポートされないため、UnionQuery と nullsFirst/Last を合わせてることはできません。 (また、パフォーマンス上の懸念が多少あるので、大量データのときには注意して下さい)
ReplaceSchemaでFKのdrop処理の抑制
SQLite用のFK制約の drop 構文に対応できていないため、ReplaceSchema のFKのdrop処理にてエラーになります。FK制約があるままでもテーブルの drop ができることを利用し(*どういうことなのか未検証)、FKのdrop処理を抑制することでReplaceSchemaが利用できます。 replaceSchemaDefinitionMap.dfprop の isSuppressDropForeignKey を有効にすることでFKのdrop処理を抑制できます。
一意制約違反の例外が不明
SQLiteの一意制約違反の判定が不明のため(SQLStateは null だし、errorCodeは常に 0 だし)、EntityAlreadyExistsException によるハンドリングができません(他のエラーと同様にSQLFailureExceptionが発生)。
更新ロックができない
SQLiteの更新ロック(for update)の構文が不明のため、ConditionBeanの lockForUpdate() は利用できません(for updateが付与されますがエラーになります)。
Exampleのススメ
SQLite を使ったExample実装 dbflute-sqlite-example があります。
DBFlute内部での取扱い
DBFlute内部でどのようにSQLiteと付き合っているか、特殊なパターンを挙げます。 将来的に同じ状況・同じ方法かどうかは保証されませんので、ここに書かれることに依存した利用はしないようにして下さい。 (DBFluteを深く理解するためのドキュメントと思って下さい)
- PreparedStatementのBigDecimalが未サポート
- PreparedStatement の setBigDecimal() がサポートされていないため、ReplaceSchema でのデータ登録処理の中でより細かい型の判定をするようにしました。
- sqlite_で始まるテーブルの(自動)除外
- 作成されたテーブルの構成次第で、自動で sqlite_ で始まる(システム)テーブルが作成され、そのままだと自動生成対象になってしまうため、DBFluteで明示的に(自動で)除外されるようにしました。
SQLite補足資料
Identity設定
PRIMARY KEY の後に AUTOINCREMENT を定義します。
e.g. Identity設定 {MEMBERのMEMBER_IDにIdentity} @DDL
create table MEMBER (
MEMBER_ID INTEGER NOT null PRIMARY KEY AUTOINCREMENT,
MEMBER_NAME TEXT NOT null,
...
) ;
発行された連番を insert 実行後に取得
e.g. 発行された連番を insert 実行後に取得 @SQL
select last_insert_rowid()