JetPack-Room

简介

android架构组件中的数据持久化组件库,是在Sqlite上实现的一条ORM(对象关系映射,Object Relational Mapping)解决方案

相关概念

  1. Database

    使用@Database注解,要求继承RoomDatabase并且是抽象类,因为创建数据库比较消耗资源,所以一般都是使用单例模式

  2. Entity

    使用@Entity注解,每个Entity都对应这数据库中的一张表

  3. DAO

    使用@Dao注解,定义了访问表的接口,主要是在里面定义增删改查方法,并在方法上使用注解添加对应的SQL语句。一般情况下一个表对应一个Dao即可

简易的创建数据库

这里简易的创建一个数据库,步骤如下

先要在app的build.gradle中添加依赖

implementation "androidx.room:room-ktx:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"

如果没有kapt,就在这个文件最上方添加(apt即表示注解处理器,kapt即kotlin annotation processing tool,因为用到了注解,所以需要这个)

apply plugin: 'kotlin-kapt'

1. 创建Entity

这里创建User类,并将表的名称重命名为users,设置主键自增

@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true) var id: Int,
    var name: String
) {
    constructor(name: String) : this(0, name)
}

当前,这里使用了数据列,使用普通类也是可以的

2. 创建DAO

@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(vararg user: User)
}

这里仅仅演示一下,插入的方法

3. 创建RoomDatabase的继承类

/**
 * 如果Entity没有对应的表,将第一次获取RoomDatabase实例的时候创建表。
 * 如果有Entity对应的表,就需要升级数据库版本号,并写对应的SQL语句
 */
@Database(
    // 所有的Entity都需要在这里注册
    entities = [User::class],
    // 版本号,升级时需要加
    version = 1
)
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao

    // 使用伴生对象创建单例
    companion object {

        private var instance: AppDatabase? = null

        fun getInstance(): AppDatabase = instance ?: synchronized(this) {
            instance ?: buildDatabase()
        }
    }
}

private fun buildDatabase(): AppDatabase = Room.databaseBuilder(
    MyApp.appInstance().applicationContext,
    AppDatabase::
    class.java,
    "room_db"
)
    .allowMainThreadQueries()//允许主线程访问,一般情况下是不允许的
    .build()

如何调用UserDao里面的insert方法呢?

AppDatabase.getInstance().userDao().insert(User("张三"))

数据库在首次使用的时候就回去创建,然后根据Entity生成对应的表。

4. 初始化数据库填充表

有的时候,在创建数据库的时候需要填充一些数据进去,那么怎么做?

只需要在创建数据库的时候设置一个监听即可。

还是上面的数据库,我们需要在创建users表的时候添加四条数据进去,如下所示

private fun buildDatabase(): AppDatabase = Room.databaseBuilder(
    MyApp.appInstance().applicationContext,
    AppDatabase::
    class.java,
    "room_db"
)
    .allowMainThreadQueries()//允许主线程访问,一般情况下是不允许的
    .addCallback(callBack) // 设置监听
    .build()

private val callBack = object : Callback() {

    /**
     * 首次创建数据库时候调用。
     * 在所有表创建完成后调用
     */
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        val sql = "INSERT INTO \n" +
                "USERS(name) \n" +
                "VALUES \n" +
                "(\"大牛\"),\n" +
                "(\"二狗\"),\n" +
                "(\"张三\"),\n" +
                "(\"李四\");";
       db.execSQL(sql)
    }

    /**
     * 数据库被打开的时候调用
     */
    override fun onOpen(db: SupportSQLiteDatabase) {
        super.onOpen(db)
    }
}

创建完成之后,先卸载之前的安装包,重新安装,然后拉出数据库查看,会发现users表已经创建,并且表中有四条数据

5. 升级数据库

有的时候,表改变了,就需要升级一下数据库。例如,我们在users表中添加列pwd,表示用户密码。

先在user类中添加变量pwd

@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true) var id: Int,
    var name: String,
    var pwd: String
) {
    constructor(name: String) : this(0, name, "")

    constructor(name: String, pwd: String) : this(0, name, pwd)
}

创建Migration的继承类

/**
 * Migration中两个参数分别表示升级前和升级后的数据库版本
 * migrate方法中写sql语句
 */
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE users ADD COLUMN pwd text NOT NULL DEFAULT \"\"")
    }
}

然后在Room.databaseBuilder创建数据库的时候添加migration

private fun buildDatabase(): AppDatabase = Room.databaseBuilder(
    MyApp.appInstance().applicationContext,
    AppDatabase::
    class.java,
    "room_db"
)
    .addMigrations(MIGRATION_1_2)
    .build()

最后,在RoomDatabase的继承类中注解中更改version

@Database(
    entities = [User::class],
    version = 2
)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值