DBFlowを使ってみたまとめ

##はじめに

DBFlowというとにかく速い(?)ライブラリを使用したので導入方法、使用方法をまとめます。
内容は**随時更新**していきます。

なお開発環境は以下のとおりです。

- AndroidStudio ver2.2.2
- DBFlow ver2.2.1


##DBFlowとは
Raizlabs社が提供しているORM(Object-relational mapping)ライブラリ。
**DBFlowはアノテーション(<code>@~</code>)を用いることでテーブルの定義などデータベース周りの処理を簡略化**できるライブラリです。


巷では速いことで有名らしいです。

※処理速度についてはRaizlabs社が[比較した結果](https://github.com/Raizlabs/AndroidDatabaseLibraryComparison)がリンク先にまとめられています。
DBFlow,GreenDAO,OrmLite,Ollie,Realmと比較しており、DBFlowが速いという結果が紹介されています。

##DBFlowの導入

導入方法、使用方法ともに[公式のドキュメント](https://agrosner.gitbooks.io/dbflow/content/)を参考にしました。
DBFlowを導入するには下記の内容を加筆する必要があります。

- build.gradle(Project)  
dependencies内に下記の内容を追記する。  

```Gradle:build.gradle
dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7'
}
```

- build.gradle(app)

```Gradle:build.gradle(app)
dependencies {
    apt 'com.raizlabs.android:DBFlow-Compiler:2.2.1'
    compile "com.raizlabs.android:DBFlow-Core:2.2.1"
    compile "com.raizlabs.android:DBFlow:2.2.1"
}
```
##DBFlowの使用方法
DBFlowを使用するには新たに2～3つのクラスを用意する必要があります。

1. (無い場合は新規作成)DBFlowを初期化するクラス(MyAppilcation.java)
2. データベースを宣言するためのクラス(AppDatabase.java)
3. テーブルを宣言するためのクラス(User.java)

###DBFlowを初期化する

<code>FlowManager.init(this)</code>によって初期化する。

```Java:MyApplication.java
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FlowManager.init(this);
    }
}

```

新たに作成した場合はAndroidManifest.xmlのapplicationタグに下記の記述を追加する。

```XML:AndroidManifest.xml

 <application
        android:name=".MyApplication" />
 </application>

```

###データベースの定義

```Java:AppDatabase.java
@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION)
public class AppDatabase {

    public static final String NAME = "AppDatabase";

    public static final int VERSION = 1;

}
```

###テーブルの定義

カラムには<code>@Column</code>、プライマリーキーには<code>@PrimaryKey</code>をつける必要があります。

```Java:User.java
@Table(databaseName = AppDatabase.NAME, tableName = "USER_TABLE")
public class User extends BaseModel { 

    @Column
    @PrimaryKey(autoincrement = true)
    int id;

    @Column(name = "NAME")
    public String name;

    @Column(name = "AGE")
    public int age;

}
```
※もちろんprivateをつけることもできます。その場合はセッター、ゲッターを忘れずに作成しましょう。

### クエリの書き方


- Insert文

```Java
        User user = new User();
        user.name = "takenoki";
        user.age = 20;
        user.insert();
```

- Select文

```SQL
select NAME from USER_TABLE where NAME = "takenoki";
```
上記のSQL文をDBFlow用に変換すると下記のようになります。

```Java
     List<User> list = new Select()
                .from(User.class)
                .where(Condition.column(User$Table.NAME).is(name))
                .queryList();
```

DBFlowではSQLで用いる句がメソッドとして用意されており、上記のほかにもdistinct(),count()なども使用できます。
今回はnameが一致するデータを取得していますが、仮に名前と年齢がともに一致するデータを取得したい場合は下記のようになります。

```Java
     List<User> list = new Select()
                .from(User.class)
                .where(
                    Condition.column(User$Table.NAME).is(name),
                    Condition.column(User$Table.AGE).is(age)
                 )
                .queryList();
```


###クエリの実行結果をListviewにセットして表示するコード

```Java
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_sample, container, false);

        String name = "takenoki";
        int age = 20;

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                act,
                android.R.layout.simple_list_item_1
        );

        List<User> list = new Select()
                .from(User.class)
                .where(Condition.column(User$Table.USER_NAME).is(name))
                .queryList();

        for (int i = 0; i < list.size(); i++) {
            adapter.add(String.valueOf(list.get(i).age));
        }

        listView.setAdapter(adapter);

        return view;
    }

```