AndroidのSQLiteの面倒臭いを簡単にする(2)
に引き続いて、CatHandsGendroidの簡単な使い方をご紹介します。今回はSQLからモデルクラスへのマッピング編です。
SQLからモデルクラスへマッピング
SQLiteDatabaseを使っていると、ときどきgroup byや集約関数を使いたくなります。
一応、標準APIでもサポートしていてメソッドもありますが、いまいち使い勝手が悪いです。
どこかでSQLを定義しておいて、メソッドを叩けばそのSQLが実行され、
モデルクラスのインスタンスが返ってくる、そういったのが欲しいものです。
なので、CatHandsGendroidにその機能を追加しました。
使い方は次のとおりです。
使い方:モデルクラスへの設定
モデルクラスのアノテーションの@DataModelにquery属性を追加します。
属性の内容はコロン(:)で名前をSQLを区切って、<名前>:<クエリー>とします。
注意点としてはSELECT文のカラム名は必ずAS句などを用いてマッピングするカラム名と一致させてください。
検索条件などに使用するプレースホルダー(?)も利用可能です。
@DataModel(
find={"id","entryId:sort+"},
query={"MaxSort:select max(sort) as sort from checkListItem where entryId=?"} // <-実行したいクエリー
)
public class CheckListItem {
@DataModelAttrs(primaryKey=true)
private Long id;
private Long entryId;
private Long sort;
private String label;
/* GetterとSetterは省略 */
}
この例からは次のようなコードがAPTによって自動生成されます。
戻り値がカーソルになっているものと、モデルクラスのリストになったものの2つになります。
public static java.util.List<CheckListItem> findByMaxSort(SQLiteDatabase db, String arg0) {
Cursor cursor = findCursorByMaxSort(db, arg0);
java.util.List<CheckListItem> result = new java.util.ArrayList<CheckListItem>();
while (cursor.moveToNext()) {
CheckListItem model = new CheckListItem();
model.setSort(ACCESSOR_SORT.readFromCursor(cursor,0));
result.add(model);
}
cursor.close();
return result;
}
public static Cursor findCursorByMaxSort(SQLiteDatabase db, String arg0) {
String[] selectionArgs = new String[]{
arg0,
};
return db.rawQuery("select max(sort) as sort from checkListItem where entryId=?", selectionArgs);
}
これらのメソッドはstaticメソッドになっていますので、使用するときは次のようにシンプルに書けます。
List<CheckListEntry> entries = CheckListEntryCatHands.findByMaxSortNo(db);
まとめ
Androidに限らずWeb系のアプリケーションでもそうですが、
データベースへのアクセス周りの処理は定型的でありながら手で書くのは面倒臭いです。
今回のようなSQLからモデルクラスへのマッピングはプログラムを書いている本人にはわかっているのに、
それを指定するパラダイムが無いので結局手でマッピングすることになることが多いです。
なのでこの手の処理はツールで機械的に生成できるなら生成し、
人の手による手間やヒューマンエラーによる不具合を避けられるように、
ツールに任せて楽ができるようにしましょう。