LoginSignup
2
1

More than 5 years have passed since last update.

AndroidのためのSquiDB

Last updated at Posted at 2018-06-10

やっぱりアプリつくるとデータをどう持つか考える必要がありますね。Androidアプリの内部DBにデータを持つことにしたので、SQLiteのライブラリとしてSquidDBを使ってみました。バージョンは3.2.3です。

設定

app/build.gradleにSquidDBを追加します。プロジェクト全体のbuild.gradleではないのでご注意を。

ついでにInjectionも追加します。

build.gradle
apply plugin: 'kotlin-kapt'

dependencies {
    ...
    // squidb
    implementation "com.yahoo.squidb:squidb:3.2.3"
    implementation 'com.yahoo.squidb:squidb-annotations:3.2.3'
    implementation 'com.yahoo.squidb:squidb-android:3.2.3'
    kapt 'com.yahoo.squidb:squidb-processor:3.2.3'

    // injection
    compile "com.google.dagger:dagger:2.8"
    kapt "com.google.dagger:dagger-compiler:2.8"
}

テーブルスキーマの定義

Personテーブルの定義を作ります。ここで定義したclassName(Personのこと)が、他のクラスから参照されるクラス名になります。ビルドするとSquiDBがジェネレイトしてくれます。

PersonSpec.kt
package com.example.myfirstapp.database

import com.yahoo.squidb.annotations.ColumnSpec
import com.yahoo.squidb.annotations.TableModelSpec

@TableModelSpec(className="Person", tableName="people")
class PersonSpec {
    private val firstName : String? = null

    private val lastName : String? = null

    @ColumnSpec(name = "creationDate")
    private val birthday : Long = 0
}

使える属性

使える属性は次のとおりです。意外なことにDate型は使えません。

  • Long
  • Integer
  • String
  • Boolean
  • Double
  • byte[] (Blob)

データベース設定

SquidDatabaseを継承して、データベース全体の定義を行います。
createOpenHelperがちょっとめんどうです。今回はこのクラスを利用する際にコンストラクタとしてcontextを追加することにします。

MyDatabase.kt
package com.example.myfirstapp.database

import android.content.Context
import com.yahoo.squidb.android.AndroidOpenHelper
import com.yahoo.squidb.data.ISQLiteDatabase
import com.yahoo.squidb.data.ISQLiteOpenHelper
import com.yahoo.squidb.data.SquidDatabase
import com.yahoo.squidb.sql.Table
import com.example.myfirstapp.database.Person

import javax.inject.Inject

class MyDatabase @Inject constructor(private  val context: Context): SquidDatabase(){
    val VERSION : Int = 1
    val NAME : String = "my-database.db"

    override fun getName(): String {
        return NAME
    }

    override fun getTables(): Array<Table> {
        return arrayOf(Person.TABLE)
    }

    override fun onUpgrade(db: ISQLiteDatabase?, oldVersion: Int, newVersion: Int): Boolean {
        return false
    }

    override fun getVersion(): Int {
        return VERSION
    }

    override fun createOpenHelper(databaseName: String?, delegate: OpenHelperDelegate?, version: Int): ISQLiteOpenHelper? {
        return AndroidOpenHelper(context,name,delegate,version)
    }

}

挿入する

これでデータベースをする準備ができました。さっそくレコードを追加してみましょう。適当なActivity上でやってみます。

val db: MyDatabase = MyDatabase(this)
val p: Person = Person()
p.firstName = "Sam"
p.lastName = "Bosley"
p.birthday = System.currentTimeMillis()
db.persist(p)

persistを実行したあとは、 p.id が設定されています。

クエリーを組み立てる

「select * from person where filest_name = "Sam"」的なクエリーです。=の他にも、>, <, and, or, join, order by, limit, offsetなどができます。

val q: Query = Query.select().where(Person.FIRST_NAME.eq("Sam"))

検索する

取得結果が複数ある場合の検索です。

val cursor: SquidCursor<Person> = db.query(Person::class.java, q)
try{
    val selectedPerson : Person = Person()
    while(cursor.moveToNext()){
       selectedPerson.readPropertiesFromCursor(cursor)
       // 検索結果を使った処理
    }
}finally {
    cursor.close()
}

取得結果が1件しかないとか、先頭1件だけつかうときはこっちでOK。

val person = db.fetchByQuery(Person::class.java, q)

更新する

1レコードだけ更新するやり方は、挿入とほぼ同じです。内部にセットされているIDを使って更新されます。

person.firstName = "Samuel"
db.persist(person)

詳細は割愛しますが、条件文を使って複数レコードを一度に更新することもできます。

削除する

削除は、IDをつかって行います。

db.delete(Person::class.java, person.id)

更新と同様に、条件文を使って複数レコードを一度に削除することもできます。

no such tableエラーになったら

アプリをエミュレータや実機で動かしていると、「no such table」エラーになる場合があります。アプリの初期インストールのときは自動的にテーブルが生成されますが、あとからテーブルを追加する場合は明示的に生成する必要があるためです。

もし(まだリリースしていない)開発中の場合だったら、エミュレータ上のアプリをアンインストールしましょう。

リリース後だったら、MyDatabaseでアップグレード時の処理を定義します。

カラム追加の場合も同様です。

MyDatabase.kt
    @Override
    protected int getVersion() {
        // これからリリースするアプリのバージョンが2
        return 2;
    }

    @Override
    protected boolean onUpgrade(ISQLiteDatabase db, int oldVersion, int newVersion) {
        switch(oldVersion) {
        case 1:
            // テーブルを追加する
            tryCreateTable(NewTable.TABLE);
        }
        return true;
    }

備考

公式ドキュメントの他に、こちらのレポジトリを参考にしました。
* kyryloz/android-budget-app
* vaibhavsonu/ModernAlarm

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1