はじめに
久しぶりにオレオレ用のAndroidアプリを書きました。
その際、DBを使ったのですが、面倒くさいことはしたくなかったので
Android向けO/R MapperであるActiveAndroid使いました。
その時のメモを備忘録な感じで残します。
準備
以下のようにして、ライブラリを自分でビルドします。
ビルド完了後、プロジェクトのビルドパスにライブラリを追加します。
1 2 3 |
|
設定
2種類の方法で利用準備ができます。
- AndroidManifest.xmlに設定する
- Applicationクラスを継承した独自のクラスを用意する
1のやり方は以下のような形で定義します。
- meta-dataタグを用意し、そこにDB名前とバージョンを記載
- android:nameに「com.activeandroid.app.Application」を記載
1 2 3 4 5 6 7 8 9 10 11 |
|
2のやり方は、以下のようにして設定内容を組み立て、起動と停止処理を組み込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
上記の内容では、以下のものを設定しています。
- キャッシュサイズ4MB
- DBを「test.db」
- バージョンを「1」
- ActiveAndroidのログを有効化(initializeメソッドのtrueのこと)
個人的には、以下の理由から組み立てて実行するほうがよいかと思います。
- ActiveAndroidの設定に引きづられず、自分のアプリに影響が出ないこと
- DBのキャッシュサイズを決められる(デフォルトが1KBのため)
- progurdによる難読化ができる(AndroidManifest.xmlに書けば見え見えになりますが、コードだと難読化ができる)
尤も、最後のはコード上でstaticに文字列として定義するとあまり意味がないですが・・・
モデル定義
以下のような感じでアノテーションをつける形で定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
アノテーションに付けれる内容は以下の表のような感じのものです。
殆どがAndroid本家のページのConstants(CONFLICT_XXXと記載されたもの)なので
こちらの説明を読んで設定すればよいかと思います。
定義先 | 定義内容 | 意味 |
---|---|---|
クラス | name | 対応するテーブル名 |
変数 | name | 対応するカラム名 |
length | 長さの制約(デフォルト -1(無制限?)) | |
notNull | not null制約(デフォルト false) | |
onNullConflict | null制約違反時の動作を設定する(デフォルトはFAIL, 設定内容はAndroid公式参照) | |
onDelete | 削除時の外部キーの動作設定(CASCADE, RESTRICT等が設定可能) | |
onUpdate | 更新時の外部キーの動作設定(CASCADE, RESTRICT等が設定可能) | |
unique | ユニーク制約(デフォルト false) | |
onUniqueConflict | ユニーク制約違反時の動作を設定\n(デフォルトはFAIL, 設定内容はAndroid公式参照) |
意味が必ずしも正しいかと言われると少し自信がありませんが、多分こんな感じかと。
また、1対Nのような関係を作るときは、getMenyメソッドを実装したヘルパーメソッドを作る必要があるようです。
クエリ
クエリについて、書いていきます。
以下を使ったことがあればすんなり理解できるかと・・・
- JavaのO/R Mapper(s2jdbc等)
- RubyのActiveRecord
挿入
以下のような感じで記載します。
ActiveRecordと殆ど同じですね。
1 2 3 |
|
以下のようにすれば、バルクインサートもできます。 また、トランザクションも併せて記載します。
1 2 3 4 5 6 7 8 9 10 11 |
|
トランザクション中にエラーが出てもthrowされないので、注意して下さい。
コンフリクト周りでエラーが出る場合は、モデルのアノテーションに定義した内容が適用されます。
削除
やり方は、以下の3種類です。
- オブジェクトをロードしてから削除する方法
- 静的メソッドを使用して削除する方法
- クエリを組み立てて削除する方法
1のやり方は、以下です。
一度、selectしてから削除という感じです。
1 2 |
|
2のやり方は、以下です。
主キーさえ分かっていれば、こちらのほうが無駄なクエリを発行しない分早いです。
1
|
|
3のやり方は、以下です。
複数の行をまとめて削除できたりします。
1
|
|
参照
これも直感的に記述できます。
使い方は、s2jdbcに似ています。
1 2 3 4 5 |
|
上記のような形で実行できます。
- 先頭1つのカラムデータのみ取得
- カラムを指定した取り方
- 条件付き(s2jdcのようにandメソッドとかはありません)
テーブル結合時は、以下のような形で記述します。
現状では、以下の方法しか手段がないようです。
- ActiveAndroidでクエリオブジェクト作成
- 1で作成したクエリオブジェクトからsqlを作成
- 2のsqlを直接実行しCursorクラスのオブジェクトを取得
- Cusorクラスからデータを取得する(whileループ等で・・・)
1 2 3 |
|
感想
こんな感じな印象でした。簡単なものだと今後も使うかも。
- ActiveRecordライクなので、扱い易い
- Modelクラスを継承したクラスを作るだけで、面倒な処理を大幅に軽減できる
- テーブル定義にコードが引きづられやすくなるので注意
- 複雑なクエリの場合、通常のSQLiteのDB操作と変わらなくなる
資料
身内向けの勉強会で、ActiveAndroidについて発表してきました。 その時、書いた資料とかも残しておきます。