【Android】DBFlowの基本的な使い方
DBFlowを使用してみたため、基本的な使い方をまとめておきます。(ver 4.0.0-beta5)
特徴
- AnnotationでModelの定義
- Modelは継承しなくても使用できるし、BaseModelの継承でModel#save()もできる
- ModelClass_Tableが自動生成され、ModelClass_Table.column_nameで各Columnにアクセスできる
- SQLらしい書き方
面倒なところ
- Columnの追加などの変更にMigrationが必要
1. AnnotationでModelの定義
ModelはAnnotationで設定ができます。
@Table(database = AppDatabase.class, name = "table_name") public class Hello{ @Unique @PrimaryKey(autoincrement = true) public int id; @Column public String title; @Column(name = "world_id") public int worldId @Column(name = "created_at") public Date createdAt; }
@Column
を記述すると、そのフィールドがColumnになります。
SQLiteでのColumn名をフィールドと違うものにする場合はname=xxx
を設定します。
2. Modelは継承しなくても使用できるし、BaseModelの継承でModel#save()もできる
継承しない場合のINSERT/UPDATEは後述。
ModelはBaseModelを継承することでModel#save()ができるようになります。
public class Hello extends BaseModel{ ... } ... hello.save();
3. Model_Tableが自動生成され、Model_Table.column_nameで各Columnにアクセスできる
WHEREを記述する場合、Modelから生成されたModel_Tableを使用して記述します。 文字列ではないため、コード補完が有効です。
WHERE id=1
.where(Hello_Table.id.eq(1));
4. SQLらしい書き方
SELECT
このようなSQLに対し、
SELECT * FROM Hello WHERE id=1
DBFlowではこのように記述します。
SQLite.select() .from(Hello.class) .where(Hello_Table.id.eq(1)); //=> Where<Hello>
1つ取得
where.querySingle(); //=> Hello
Listで取得
where.queryList(); //=> List<Hello>
Count
countの場合は少し特殊でselectCountOf
を使用します。
SQLite.selectCountOf() .from(Hello.class) .where(Hello_Table.world_id.eq(worldId)); .count(); //=> long
INSERT/UPDATE
INSERT/UPDATEは2種類の方法があります。
BaseModelの継承あり
BaseModelを継承した場合は、前述の通り、Model#save()で行います。
hello.save();
BaseModelの継承なし
継承しなくて済むならJavaのclassの制約に苦しまなくて済むためこちらを使用しています。 ただ、insert/updateを真面目に記述するのも面倒なため、 できれば上述のModel#save()のような方法の方が望ましく思います。
その場合、FlowManagerからAdapterを取得して、
ModelAdapter<Hello> adapter = FlowManager.getModelAdapter(Hello.class);
insertや
long id = adapter.insert(hello);
updateを行うことで
adapter.update(hello);
BaseModelを継承しなくてもsave()と同様のことができます。
DELETE
DELETEはSELECTとほぼ同様です。
SQLite.delete() .from(Hello.class) .where(Hello_Table.id.eq(1)) .execute();
面倒なところ
仕方のないことかもしれませんが、Columnの追加などの変更の際にMigrationが必要です。
Migration
Columnの追加
Helloモデルにworld
のColumnを追加する場合は、ModelにColumnを追加し、
public class Hello{ ... @Column public int world; }
MigrationをDatabaseクラスに記述します。
@Migration(version = 2, database = AppDatabase.class) public static class Migration2 extends AlterTableMigration<Hello>{ public Migration2(Class<Hello> table){ super(table); } @Override public void onPreMigrate() { addColumn(SQLiteType.INTEGER, Hello_Table.world.toString()); } }
その他
SELECT/INSERTが速い
天下一「AndroidのORM」武道会(2015年版)の速さランキングで上位にランクインしています。
GitHubのStar
2017年1月現在のStarの数です
- DBFlow 3,131
- greenDAO 6,634
- ActiveAndroid 4,240
- Orma 309
所感
今回は速さランキングを参考にSQLiteの中から上記の選択肢に絞り、
速さ/安定/コードの書き方/学習コストといった点から最終的にDBFlowにしました。
見送った主な理由は以下の通りです。
- greenDAO
- generatorの記述が面倒
- ActiveAndroid
- ManifestにModelの記述が必要、GitHubの更新が途絶えている
- Orma
- やり方が悪いのかColumnを追加後に動かなくなった