Android数据库组件Room

Room是Android官方提供的sqlite数据库管理组件。java

添加依赖

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/build/room/schemas".toString()]
            }
        }
    }
    ...
}

dependencies {
    ...
    def room_version = "1.1.1"
    implementation "android.arch.persistence.room:runtime:$room_version"
    kapt "android.arch.persistence.room:compiler:$room_version" 
    implementation "android.arch.persistence.room:rxjava2:$room_version"
    implementation "android.arch.persistence.room:guava:$room_version"
    testImplementation "android.arch.persistence.room:testing:$room_version"
}

建立数据库

val accountDB: AccountDB = Room.databaseBuilder(context, AccountDB::class.java, "account.db")
            .allowMainThreadQueries()//容许在主线程查询(若是不容许主线程查询,能够使用LiveData)
            .fallbackToDestructiveMigration()//数据库版本更新,清空数据库
            .addMigrations(migration_1_2)//数据库版本更新,修改数据库
            .build()
@Database(entities = [User::class, Phone::class], version = 1)
abstract class AccountDB : RoomDatabase() {

    abstract fun userDao(): UserDao

    abstract fun phoneDao(): PhoneDao

}

定义实体表

@Entity(tableName = "user")
class User {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var id: Long = 0

    @ColumnInfo(name = "nickname")
    var nickname: String = ""

    @ColumnInfo(name = "birthday")
    var birthday: Long = 0

    @Ignore
    var picture: Bitmap? = null

}
@Entity(tableName = "phone")
class Phone {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var id: Long = 0

    @ColumnInfo(name = "num")
    var num: String = ""

    @ColumnInfo(name = "userId")
    var userId: Long = 0

}

Dao类

@Dao
interface UserDao {

    @Query("SELECT * FROM user")
    fun query(): List<User>

    @Query("SELECT * FROM user")
    fun queryLiveData(): LiveData<List<User>>

    @Query("SELECT * FROM user WHERE id IN (:userIds)")
    fun queryByIds(vararg userIds: Int): List<User>

    @Query("SELECT * FROM user WHERE nickname LIKE :nickname")
    fun queryByNickname(nickname: String): List<User>

    @Insert
    fun insert(user: User):Long

    @Update
    fun update(user: User):Int

    @Delete
    fun delete(user: User):Int

    @Transaction
    @Query("SELECT * FROM user")
    fun queryUserAndPhone(): List<UserAndPhone>

}
@Dao
interface PhoneDao {

    @Insert
    fun insert(phone: Phone):Long

}

数据库查询

val accountDB = Room.databaseBuilder(App.context, AccountDB::class.java, "account.db")
    .allowMainThreadQueries()
    .build()
val user = User()
accountDB.userDao().insert(user)//新增
accountDB.userDao().query()//查询
accountDB.userDao().update(user)//修改
accountDB.userDao().delete(user)//删除

事务处理

val accountDB = Room.databaseBuilder(App.context, AccountDB::class.java, "account.db")
    .allowMainThreadQueries()
    .build()
try {
    //执行事务
    accountDB.runInTransaction {
        val user = User()

        //插入数据
        DBUtil.accountDB.userDao().insert(user)

        "a".toInt()//异常
    }
} catch (e: Exception) {
    e.printStackTrace()
    Toast.makeText(this, "异常,数据回滚", Toast.LENGTH_SHORT).show()
}

LiveData查询

val accountDB = Room.databaseBuilder(App.context, AccountDB::class.java, "account.db")
    .allowMainThreadQueries()
    .build()
accountDB.userDao().queryLiveData().observe(this, Observer {list->
    log(list.toString())
})

关联查询

class UserAndPhone {

    @Embedded
    var user: User = User()

    @Relation(parentColumn = "id", entityColumn = "userId")
    var phoneList: List<Phone> = ArrayList()

    override fun toString(): String {
        return "UserAndPhone(user=$user, phoneList=$phoneList)"
    }

}
@Dao
interface UserDao {

    @Transaction
    @Query("SELECT * FROM user")
    fun queryUserAndPhone(): List<UserAndPhone>

}

数据库版本更新

val migration_1_2: Migration = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE user ADD birthday INTEGER NOT NULL DEFAULT 0")
    }
}

val accountDB = Room.databaseBuilder(App.context, AccountDB::class.java, "account.db")
    .allowMainThreadQueries()
    .addMigrations(migration_1_2)
    .build()

RoomDemo:https://github.com/dingjianlun/RoomDemoandroid