Jetpack Room

Jetpack Room

概述

  • Google推出的Jetpack组件之一
  • 功能强大,使用简单,支持数据库监听等

添加依赖

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
}

dependencies {
    def room_version = "2.3.0"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor "androidx.room:room-compiler:$room_version"
    kapt("androidx.room:room-compiler:$room_version")
}

Room组成部分

Room主要由三个部分组成:

  • DataBase:数据库持有者。
  • Entity:数据库中对应的表。
  • DAO:提供访问数据库的方法。

开发者需要使用DataBase获取DAO对象,通过DAO操作Entity,Room数据库相关操作必须在子线程中执行。

在这里插入图片描述

配置数据库

定义Entity

@Entity
data class User(var firstName: String, var lastName: String, var age: Int) {
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0
}

定义Dao

@Dao
interface UserDao {
    @Insert
    fun insertUser(user: User)

    @Insert
    fun insertAllUser(user: List<User>)

    @Update
    fun updateUser(newUser: User)

    @Query("update User set age=100 where age= :age")
    fun updateUserWithAge(age: Int)

    @Query("select * from User")
    fun queryAllUsers(): List<User>

    @Query("select * from User where age >= :age")
    fun queryUserByAge(age: Int): List<User>

    @Delete
    fun deleteUser(user: User)

    @Query("delete from User where age = :age")
    fun deleteUserByAge(age: Int): Int
}

定义Database

@Database(version = 1, entities = [User::class])
abstract class MyRoomDatabase : RoomDatabase() {
    companion object {
        private var instance: MyRoomDatabase? = null
        private const val DB_NAME = "myroom"

        @Synchronized
        fun getDatabase(context: Context): MyRoomDatabase {
            instance?.let {
                return it
            }
            return Room.databaseBuilder(
                context.applicationContext,
                MyRoomDatabase::class.java,
                DB_NAME
            ).build().apply {
                instance = this
            }
        }
    }
    
    abstract fun userDao(): UserDao
}

初始化操作

userDao = MyRoomDatabase.getDatabase(this).userDao()

操作数据库

增加数据

增加一条数据

val user = User("小", "明", 18)
userDao.insertUser(user)

增加多条数据

val userList =
arrayListOf<User>(
    User("小", "白", 18),
    User("小", "黑", 28),
    User("大", "白", 38),
    User("大", "黑", 48)
)
userDao.insertAllUser(userList)

删除数据

删除条件数据

userDao.deleteUserByAge(28)

修改数据

修改条件数据

userDao.updateUserWithAge(48)

修改数据根据主键

val userList = userDao.queryUserByAge(20)
for (user in userList) {
    user.age = 1000
    userDao.updateUser(user)
}

查询数据

查询所有数据

val userList = userDao.queryAllUsers()

查询条件数据

val userList = userDao.queryUserByAge(20)

事务

//方式一
//使用注解
@Transaction
private fun transaction1() {
    thread {
        userDao.insertUser(User("李", "四", 28))
        userDao.insertUser(User("张", "三", 18))
        userDao.deleteUserByAge(28)
    }
}

//方式二
//使用runInTransaction
private fun transaction2() {
    thread {
        MyRoomDatabase.getDatabase(this).runInTransaction {
            userDao.insertUser(User("李", "四", 28))
            userDao.insertUser(User("张", "三", 18))
            userDao.deleteUserByAge(28)
        }
    }
}

高级用法

嵌套对象

data class Address(var addr: String?, var detailAddress: String?)

@Entity
data class Consumer(
    var name: String,
    var age: Int,
    @Embedded
    var address: Address? = null
) {
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0L
}

注:最终Consumer表中一共有:id、name、age、addr、detailAddress字段

一对一

//Entity

@Entity
data class Consumer(
    var name: String,
    var age: Int,
    @Embedded
    var address: Address? = null
) {
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0L
}


@Entity
data class Library(
    var libraryName: String,
    var consumerId: Long
) {
    @PrimaryKey(autoGenerate = true)
    var libraryId: Long = 0L
}

//一对一关联类
data class ConsumerAndLibrary(
    @Embedded
    var consumer: Consumer,
    @Relation(parentColumn = "id", entityColumn = "consumerId")
    var library: Library
)
//Dao

//一对一查询
@Transaction
@Query("SELECT * FROM Consumer")
fun getConsumerAndLibraryList(): List<ConsumerAndLibrary>

查询操作:

val consumerAndLibraryList =
MyRoomDatabase.getDatabase(this).libraryDao().getConsumerAndLibraryList()
for (i in consumerAndLibraryList) {
    log(i)
}
ConsumerAndLibrary(consumer=Consumer(name=小明, age=18, address=null), library=Library(libraryName=歌曲4, consumerId=1))
ConsumerAndLibrary(consumer=Consumer(name=小黑, age=28, address=null), library=Library(libraryName=歌曲5, consumerId=2))
ConsumerAndLibrary(consumer=Consumer(name=小白, age=38, address=null), library=Library(libraryName=歌曲6, consumerId=3))

一对多

//一对多关联
data class ConsumerAndLibrarys(
    @Embedded
    var consumer: Consumer,
    @Relation(parentColumn = "id", entityColumn = "consumerId")
    var library: List<Library>
)
//Dao

//一对多查询
@Transaction
@Query("SELECT * FROM Consumer")
fun getConsumerAndLibrarysList(): List<ConsumerAndLibrarys>

查询操作:

val consumerAndLibrarysList =
MyRoomDatabase.getDatabase(this).libraryDao().getConsumerAndLibrarysList()
for (i in consumerAndLibrarysList) {
    log(i)
}
ConsumerAndLibrarys(consumer=Consumer(name=小明, age=18, address=null), library=[Library(libraryName=歌曲1, consumerId=1), Library(libraryName=歌曲4, consumerId=1)])
ConsumerAndLibrarys(consumer=Consumer(name=小黑, age=28, address=null), library=[Library(libraryName=歌曲2, consumerId=2), Library(libraryName=歌曲5, consumerId=2)])
ConsumerAndLibrarys(consumer=Consumer(name=小白, age=38, address=null), library=[Library(libraryName=歌曲3, consumerId=3), Library(libraryName=歌曲6, consumerId=3)])

数据库升级

  • Room会触发所有迁移策略,一个接着一个执行

新增表

新建Entity类

@Entity
data class Book(var name: String, var pages: Int) {

    @PrimaryKey(autoGenerate = true)
    var id = 0L

}

配置升级信息

private const val DB_NAME = "myroom"
private const val DB_VERSION = 2

@Database(version = DB_VERSION, entities = [User::class, Book::class])
abstract class MyRoomDatabase : RoomDatabase() {

    companion object {
        private var instance: MyRoomDatabase? = null

        //版本1升级到版本2策略
        private val updateVersion_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                val sql =
                "create table Book(id integer primary key autoincrement not null, name text not null, pages integer not null)"
                database.execSQL(sql)
            }
        }

        @Synchronized
        fun getDatabase(context: Context): MyRoomDatabase {
            instance?.let {
                return it
            }
            return Room.databaseBuilder(
                context.applicationContext,
                MyRoomDatabase::class.java,
                DB_NAME
            )
            .addMigrations(updateVersion_1_2)
            .build().apply {
                instance = this
            }
        }
    }

}

新增表字段

修改配置类

private const val DB_NAME = "myroom"
private const val DB_VERSION = 3

@Database(version = DB_VERSION, entities = [User::class, Book::class])
abstract class MyRoomDatabase : RoomDatabase() {

    companion object {
        private var instance: MyRoomDatabase? = null


        //版本1升级到版本2策略
        private val updateVersion_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                val sql =
                    "create table Book(id integer primary key autoincrement not null, name text not null, pages integer not null)"
                database.execSQL(sql)
            }
        }

        //版本2升级到版本3
        private val updateVersion_2_3 = object : Migration(2, 3) {
            override fun migrate(database: SupportSQLiteDatabase) {
                val sql = "alter table Book add column info text not null default 'unknown'"
                database.execSQL(sql)
            }
        }

        @Synchronized
        fun getDatabase(context: Context): MyRoomDatabase {
            instance?.let {
                return it
            }
            return Room.databaseBuilder(
                context.applicationContext,
                MyRoomDatabase::class.java,
                DB_NAME
            )
                .addMigrations(updateVersion_1_2, updateVersion_2_3)
                .build().apply {
                    instance = this
                }
        }
    }

}

修改Entity类

@Entity
data class Book(var name: String, var pages: Int, var info: String) {

    @PrimaryKey(autoGenerate = true)
    var id = 0L

}

源码下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值