Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )

【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )

作者头像
韩曙亮
发布于 2023-10-11 09:47:14
发布于 2023-10-11 09:47:14
51700
代码可运行
举报
运行总次数:0
代码可运行

一、销毁 和 重建策略

Android 中使用 Room 操作 SQLite 数据库 , 如果 SQLite 数据库表 修改比较繁琐 ,

如 : 涉及到 修改 数据库表字段的数据类型 , 需要逐个修改数据库值 ;

该环境下 使用 销毁 和 重建策略 是 最佳的方案 ;

销毁 和 重建策略 执行步骤 : 以 Table 表为例 , 要对 Table 表中的数据进行繁琐的操作 ;

  • 首先 , 创建一张 符合 新数据库表结构 的 临时数据库表 Temp_Table 表 ;
  • 然后 , 将 旧数据库表 Table 表中的数据 拷贝到 临时数据库表 Temp_Table 表中 , 如果需要修改 , 也在该步骤中进行修改 ;
  • 再后 , 删除旧的数据库表 Table 表 ;
  • 最后 , 将 临时数据库表 Temp_Table 表 重命名为 Table 表 ;

二、销毁 和 重建策略 核心要点

1、创建 Migration 迁移类 - 重点

在本篇博客中 , 在之前的博客

基础上 , 升级数据库版本 4 ;

数据库 版本 2 和 3 分别在 数据库 版本 1 的基础上新增了一个字段 ;

这里要升级的数据库版本 4 , 要 在 数据库版本 3 的基础上 , 将 integer 类型的字段 sex 的 数据类型 修改为 text 类型 ,

这就需要将 整个数据库表中的数据的 指定字段 需要重新赋值 ;

这就需要 使用 销毁重建 策略 ;

销毁 和 重建策略 执行步骤 :

  • 首先 , 创建一张 符合 新数据库表结构 的 临时数据库表;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
                // 创新临时数据库
                database.execSQL(
                    "CREATE TABLE temp_student (" +
                            "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                            "name TEXT," +
                            "age INTEGER NOT NULL," +
                            "sex TEXT DEFAULT 'M'," +
                            "degree INTEGER NOT NULL DEFAULT 1)"
                )
  • 然后 , 将 旧数据库表 中的数据 拷贝到 临时数据库表 中 , 如果需要修改 , 也在该步骤中进行修改 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
                // 拷贝数据
                database.execSQL(
                    "INSERT INTO temp_student (name,age,degree)" +
                            "SELECT name,age,degree FROM student"
                )
  • 再后 , 删除旧的数据库表 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
                // 删除原始表
                database.execSQL("DROP TABLE student")
  • 最后 , 将 临时数据库表 重命名为 原来的表名 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
                // 将临时表命令为原表表明
                database.execSQL("ALTER TABLE temp_student RENAME TO student")

上述的 四个步骤 , 都在 Migration 的 public void migrate(@NonNull SupportSQLiteDatabase database) 函数中完成 , 每个步骤分别对应一个 SQL 语句 ;

最终定义的 Migration 为 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        /**
         * 数据库版本 3 升级到 版本 4 的迁移类实例对象
         * 销毁重建策略
         */
        val MIGRATION_3_4: Migration = object : Migration(3, 4) {
            override fun migrate(database: SupportSQLiteDatabase) {
                // 创新临时数据库
                database.execSQL(
                    "CREATE TABLE temp_student (" +
                            "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                            "name TEXT," +
                            "age INTEGER NOT NULL," +
                            "sex TEXT DEFAULT 'M'," +
                            "degree INTEGER NOT NULL DEFAULT 1)"
                )

                // 拷贝数据
                database.execSQL(
                    "INSERT INTO temp_student (name,age,degree)" +
                            "SELECT name,age,degree FROM student"
                )

                // 删除原始表
                database.execSQL("DROP TABLE student")

                // 将临时表命令为原表表明
                database.execSQL("ALTER TABLE temp_student RENAME TO student")
            }
        }

2、配置 Migration 迁移类

在 创建 RoomDatabase.Builder 时 , 调用 RoomDatabase.Builder#addMigrations , 设置上述创建的 销毁重建策略的 Migration 迁移类 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        fun inst(context: Context): StudentDatabase {
            if (!::instance.isInitialized) {
                synchronized(StudentDatabase::class) {
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        .addMigrations(MIGRATION_1_2)
                        .addMigrations(MIGRATION_2_3)
                        .addMigrations(MIGRATION_3_4)
                        .fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }

3、修改数据库版本号

在 RoomDatabase 类的 @Database 注解上的 version 数据库版本号参数设置为 4 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Database(entities = [Student::class], version = 4, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {

4、修改实体类数据类型

将 Entity 实体类 Student 类中的 sex 字段 由

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0

修改为 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 TEXT 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.TEXT)
    var sex: String = "M"

三、完整代码示例

代码地址 : https://github.com/han1202012/Room_ViewModel_LiveData

1、数据库版本 3 代码示例

RoomDatabase 数据库类完整代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.rvl

import android.content.Context
import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(entities = [Student::class], version = 3, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    /**
     * 获取 数据库访问 对象
     * 这是必须要实现的函数
     */
    abstract fun studentDao(): StudentDao

    companion object {
        lateinit var instance: StudentDatabase

        /**
         * 数据库版本 1 升级到 版本 2 的迁移类实例对象
         */
        val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                Log.i("Room_StudentDatabase", "数据库版本 1 升级到 版本 2")
                database.execSQL("alter table student add column sex integer not null default 1")
            }
        }

        /**
         * 数据库版本 2 升级到 版本 3 的迁移类实例对象
         */
        val MIGRATION_2_3: Migration = object : Migration(2, 3) {
            override fun migrate(database: SupportSQLiteDatabase) {
                Log.i("Room_StudentDatabase", "数据库版本 2 升级到 版本 3")
                database.execSQL("alter table student add column degree integer not null default 1")
            }
        }

        fun inst(context: Context): StudentDatabase {
            if (!::instance.isInitialized) {
                synchronized(StudentDatabase::class) {
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        .addMigrations(MIGRATION_1_2)
                        .addMigrations(MIGRATION_2_3)
                        .fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }
    }
}
Student 实体类完整代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.rvl

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey

/**
 * 定义数据库表 Entity 实体 / 同时定义数据库表 和 对鹰的实体类
 * 设置该数据类对应数据库中的一张数据表, 表名为 student
 * 该数据库表中的数据对应一个 Student 类实例对象
 */
@Entity(tableName = "student")
class Student {
    /**
     * @PrimaryKey 设置主键 autoGenerate 为自增
     * @ColumnInfo name 设置列名称 / typeAffinity 设置列类型
     */
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    var id: Int = 0

    /**
     * 姓名字段
     * 数据库表中的列名为 name
     * 数据库表中的类型为 TEXT 文本类型
     */
    @ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
    lateinit var name: String

    /**
     * 年龄字段
     * 数据库表中的列名为 age
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)
    var age: Int = 0

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0

    /**
     * degree字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "degree", typeAffinity = ColumnInfo.INTEGER)
    var degree: Int = 0

    /**
     * 有些属性用于做业务逻辑
     * 不需要插入到数据库中
     * 使用 @Ignore 注解修饰该属性字段
     */
    @Ignore
    lateinit var studentInfo: String

    /**
     * 默认的构造方法给 Room 框架使用
     */
    constructor(id: Int, name: String, age: Int) {
        this.id = id
        this.name = name
        this.age = age
    }

    /**
     * 使用 @Ignore 标签标注后
     * Room 就不会使用该构造方法了
     * 这个构造方法是给开发者使用的
     */
    @Ignore
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }

    /**
     * 使用 @Ignore 标签标注后
     * Room 就不会使用该构造方法了
     * 这个构造方法是给开发者使用的
     */
    @Ignore
    constructor(id: Int) {
        this.id = id
    }

    override fun toString(): String {
        return "Student(id=$id, name='$name', age=$age)"
    }
}
执行结果

先执行数据库版本为 3 的应用 , 输出结果如下 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2023-06-05 19:17:12.251 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: []
2023-06-05 19:17:12.532 I/Room_MainActivity: 插入数据 S1 : Student(id=0, name='Tom', age=18)
2023-06-05 19:17:12.536 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Tom', age=18)]
2023-06-05 19:17:13.036 I/Room_MainActivity: 插入数据 S2 : Student(id=0, name='Jerry', age=16)
2023-06-05 19:17:13.038 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Tom', age=18), Student(id=2, name='Jerry', age=16)]
2023-06-05 19:17:13.538 I/Room_MainActivity: 更新数据 S2 : Student(id=2, name='Jack', age=60)
2023-06-05 19:17:13.540 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Tom', age=18), Student(id=2, name='Jack', age=60)]
2023-06-05 19:17:14.051 I/Room_MainActivity: 删除数据 id = 1
2023-06-05 19:17:14.060 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=2, name='Jack', age=60)]
2023-06-05 19:17:14.553 I/Room_MainActivity: 主动查询 : LiveData : androidx.room.RoomTrackingLiveData@8726677 , 实际数据 : null
2023-06-05 19:17:14.554 I/Room_MainActivity: 主动查询2 : [Student(id=2, name='Jack', age=60)]

2、数据库版本 4 代码示例

将数据库版本修改为 4 , 然后执行上述 销毁重建策略 修改 ;

主要是创建了 数据库版本 3 升级到 版本 4 的迁移类实例对象 , 该 Migration 类

RoomDatabase 数据库类完整代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.rvl

import android.content.Context
import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(entities = [Student::class], version = 4, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    /**
     * 获取 数据库访问 对象
     * 这是必须要实现的函数
     */
    abstract fun studentDao(): StudentDao

    companion object {
        lateinit var instance: StudentDatabase

        /**
         * 数据库版本 1 升级到 版本 2 的迁移类实例对象
         */
        val MIGRATION_1_2: Migration = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                Log.i("Room_StudentDatabase", "数据库版本 1 升级到 版本 2")
                database.execSQL("alter table student add column sex integer not null default 1")
            }
        }

        /**
         * 数据库版本 2 升级到 版本 3 的迁移类实例对象
         */
        val MIGRATION_2_3: Migration = object : Migration(2, 3) {
            override fun migrate(database: SupportSQLiteDatabase) {
                Log.i("Room_StudentDatabase", "数据库版本 2 升级到 版本 3")
                database.execSQL("alter table student add column degree integer not null default 1")
            }
        }

        /**
         * 数据库版本 3 升级到 版本 4 的迁移类实例对象
         * 销毁重建策略
         */
        val MIGRATION_3_4: Migration = object : Migration(3, 4) {
            override fun migrate(database: SupportSQLiteDatabase) {
                Log.i("Room_StudentDatabase", "数据库版本 3 升级到 版本 4")
                // 创新临时数据库
                database.execSQL(
                    "CREATE TABLE temp_student (" +
                            "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                            "name TEXT," +
                            "age INTEGER NOT NULL," +
                            "sex TEXT NOT NULL DEFAULT 'M'," +
                            "degree INTEGER NOT NULL DEFAULT 1)"
                )

                // 拷贝数据
                database.execSQL(
                    "INSERT INTO temp_student (name, age, degree)" +
                            "SELECT name, age, degree FROM student"
                )

                // 删除原始表
                database.execSQL("DROP TABLE student")

                // 将临时表命令为原表表明
                database.execSQL("ALTER TABLE temp_student RENAME TO student")
            }
        }

        fun inst(context: Context): StudentDatabase {
            if (!::instance.isInitialized) {
                synchronized(StudentDatabase::class) {
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        .addMigrations(MIGRATION_1_2)
                        .addMigrations(MIGRATION_2_3)
                        .addMigrations(MIGRATION_3_4)
                        .fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }
    }
}
Student 实体类代码示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.rvl

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey

/**
 * 定义数据库表 Entity 实体 / 同时定义数据库表 和 对鹰的实体类
 * 设置该数据类对应数据库中的一张数据表, 表名为 student
 * 该数据库表中的数据对应一个 Student 类实例对象
 */
@Entity(tableName = "student")
class Student {
    /**
     * @PrimaryKey 设置主键 autoGenerate 为自增
     * @ColumnInfo name 设置列名称 / typeAffinity 设置列类型
     */
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    var id: Int = 0

    /**
     * 姓名字段
     * 数据库表中的列名为 name
     * 数据库表中的类型为 TEXT 文本类型
     */
    @ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
    lateinit var name: String

    /**
     * 年龄字段
     * 数据库表中的列名为 age
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)
    var age: Int = 0

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 TEXT 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.TEXT)
    var sex: String = "M"

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    /*@ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0*/

    /**
     * degree字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "degree", typeAffinity = ColumnInfo.INTEGER)
    var degree: Int = 0

    /**
     * 有些属性用于做业务逻辑
     * 不需要插入到数据库中
     * 使用 @Ignore 注解修饰该属性字段
     */
    @Ignore
    lateinit var studentInfo: String

    /**
     * 默认的构造方法给 Room 框架使用
     */
    constructor(id: Int, name: String, age: Int) {
        this.id = id
        this.name = name
        this.age = age
    }

    /**
     * 使用 @Ignore 标签标注后
     * Room 就不会使用该构造方法了
     * 这个构造方法是给开发者使用的
     */
    @Ignore
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }

    /**
     * 使用 @Ignore 标签标注后
     * Room 就不会使用该构造方法了
     * 这个构造方法是给开发者使用的
     */
    @Ignore
    constructor(id: Int) {
        this.id = id
    }

    override fun toString(): String {
        return "Student(id=$id, name='$name', age=$age)"
    }
}
执行结果

执行结果如下 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2023-06-05 19:18:58.864 I/Room_StudentDatabase: 数据库版本 3 升级到 版本 4
2023-06-05 19:18:58.909 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Jack', age=60)]
2023-06-05 19:18:59.346 I/Room_MainActivity: 插入数据 S1 : Student(id=0, name='Tom', age=18)
2023-06-05 19:18:59.351 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Jack', age=60), Student(id=2, name='Tom', age=18)]
2023-06-05 19:18:59.853 I/Room_MainActivity: 插入数据 S2 : Student(id=0, name='Jerry', age=16)
2023-06-05 19:18:59.855 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Jack', age=60), Student(id=2, name='Tom', age=18), Student(id=3, name='Jerry', age=16)]
2023-06-05 19:19:00.362 I/Room_MainActivity: 更新数据 S2 : Student(id=2, name='Jack', age=60)
2023-06-05 19:19:00.371 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=1, name='Jack', age=60), Student(id=2, name='Jack', age=60), Student(id=3, name='Jerry', age=16)]
2023-06-05 19:19:00.875 I/Room_MainActivity: 删除数据 id = 1
2023-06-05 19:19:00.877 I/Room_MainActivity: Observer#onChanged 回调, List<Student>: [Student(id=2, name='Jack', age=60), Student(id=3, name='Jerry', age=16)]
2023-06-05 19:19:01.377 I/Room_MainActivity: 主动查询 : LiveData : androidx.room.RoomTrackingLiveData@b957950 , 实际数据 : null
2023-06-05 19:19:01.378 I/Room_MainActivity: 主动查询2 : [Student(id=2, name='Jack', age=60), Student(id=3, name='Jerry', age=16)]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Jetpack】Room 预填充数据 ( 安装 DB Browser for SQLite 工具 | 创建数据库文件 | 应用中设预填充数据对应的数据库文件 | 预填充数据库表字段属性必须一致 )
在 Android 中使用 Room 框架 , 创建 SQLite 数据库时 , 有时需要预填充一些数据 , 这些数据一般都是来自 assets 资源目录 ;
韩曙亮
2023/10/11
7010
【Jetpack】Room 预填充数据 ( 安装 DB Browser for SQLite 工具 | 创建数据库文件 | 应用中设预填充数据对应的数据库文件 | 预填充数据库表字段属性必须一致 )
【Jetpack】使用 Room 中的 Migration 升级数据库异常处理 ( 多个数据库版本的迁移 | fallbackToDestructiveMigration() 函数处理升级异常 )
Room Migration 数据库迁移工具 是 Android Jetpack Architecture Components ( 架构组件 ) 的一部分 , 它是一个方便的 数据库迁移工具 , 用于为 Android 中使用 Room 框架创建的数据库 提供 自动化迁移方案 ;
韩曙亮
2023/10/11
6430
【Jetpack】使用 Room 中的 Migration 升级数据库异常处理 ( 多个数据库版本的迁移 | fallbackToDestructiveMigration() 函数处理升级异常 )
【Jetpack】使用 Room Migration 升级数据库并导出 Schema 文件 ( Schema 文件简介 | 生成 Schema 文件配置 | 生成 Schema 文件过程 )
使用 Room Migration 升级数据库 , 需要根据当前数据库版本和目标版本编写一系列 Migration 迁移类 , 并生成一个升级的 Schema 文件 , 该文件是 json 格式的文件 , 其中包含如下内容 :
韩曙亮
2023/10/11
4440
【Jetpack】使用 Room Migration 升级数据库并导出 Schema 文件 ( Schema 文件简介 | 生成 Schema 文件配置 | 生成 Schema 文件过程 )
【Jetpack】使用 Room 中的 Migration 升级数据库 ( 修改 Entity 实体类 - 更改数据模型 | 创建 Migration 迁移类 | 修改数据库版本 | 代码示例 )
使用 Room 访问数据库时 , 应用程序 的 数据模型 发生 改变 , 数据库版本进行升级 , 数据库表的字段 , 数据结构 , 发生了变化 , 需要进行更新 , 可以使用 Migration 迁移工具 升级数据库 ;
韩曙亮
2023/10/11
1.5K0
【Jetpack】使用 Room 中的 Migration 升级数据库 ( 修改 Entity 实体类 - 更改数据模型 | 创建 Migration 迁移类 | 修改数据库版本 | 代码示例 )
Jetpack组件之Room
Android使用SQLite作为数据库存储数据,但是SQLite使用繁琐且容易出错,有许多开源的数据如GreenDAO、ORMLite等,这些都是为了方便SQLite的使用而出现的,Google也意识到了这个问题,在Jetpack组件中推出了Room,Room在SQLite上提供了一层封装,可以流畅的访问数据库。
八归少年
2022/06/29
2K0
Jetpack组件之Room
【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 )
对于 Room 框架 来说 , 使用 Java 语言 开发和使用 Kotlin 语言 开发 , 需要在 build.gradle 构建脚本 中进行不同的配置 , 主要有以下两个配置不同 :
韩曙亮
2023/10/11
5650
JetPack--Room数据库
定义一个实体类,在class上使用 @Entity注解 ,还需要一个构造方法,Room会根据这个构造将表里的数据转化为实体类,对于其他我们代码里使用的构造方法,可以使用@Ignore注解表示Room将忽略它,属性也可以使用这个注解,表示这个属性将不会生成数据库字段 使用@PrimaryKey注解指定主键并且是自增长的 属性还可以指定在数据库的字段等,使用@ColumnInfo注解:
aruba
2021/12/06
1.5K0
JetPack--Room数据库
【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )
在上一篇博客 【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 ) 中 , 实现了 使用 Room 框架访问 Android 中的 SQLite 数据库的操作 , 每当数据库中的数据发生变化时 , 就需要开启线程 , 重新获取数据库中的数据 ;
韩曙亮
2023/10/11
1.1K0
【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )
Jetpack之Room的使用,结合Flow
如需在应用中使用Room,请将以下依赖项添加到应用的 build.gradle文件。
yechaoa
2022/06/10
1.2K0
Jetpack之Room的使用,结合Flow
Jetpack Room使用
数据库有多张表,一张表只能记录一种Class,Class的具体属性是这个表的列;所有对表的操作都要通过Dao来访问
北洋
2022/05/10
3620
Android—Room 数据库迁移(Migration)
前言 如果大家看到了这里,那大家就可以正常使用Room数据库了。因为业务的变更,我们时常会添加数据库字段。这时候咱们就需要去升级数据库了。 如果咱们删除了一个字段,运行程序后,就会出现下面这个问题。 java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can
code_horse
2018/07/02
2.8K1
Android Room数据库版本迁移的实战
最近一直在做一款Android的新产品,所以更新的文章基本都是Android相关,主要是产品中的应用的东西及一些笔记,新产品中Android本地数据库要存放的东西还挺多的,所以这篇是专门针对Android本地数据库Room的版本迁移做的一个填坑记录。
Vaccae
2021/10/25
2K0
Android Room数据库版本迁移的实战
Android的room数据库使用小结(kotlin)
Room是Google官方推荐使用的数据库,相比较某些优秀数据库框架来说,不用过于担心某天库会停止维护,且访问数据库非常流畅,并且提供了与常规的ORM框架一样,通过添加编译期注解来进行表和字段的配置,譬如@Database、@Dao、@Entity、@Query、@Insert、@Update、@Detele等的注解,可以使用简单代码实现相比以前SQLite更复杂的代码的效果,这点儿有点儿类似于java世界里的mybatis。总而言之, Room功能强大,速度和稳定性不弱,还简单易用,算得上是一个优秀的数据库。
杨永贞
2021/06/02
3.3K0
Android的room数据库使用小结(kotlin)
room的使用-以demo为例
前言 本文是以demo为例介绍,所以部分内容和解释会在demo里以注释的形式给出。 下载链接 数据库的构建 环境配置 在app模块的build.gradle添加以下内容: compile 'android.arch.lifecycle:extensions:1.0.0-alpha5' compile 'android.arch.lifecycle:runtime:1.0.0-alpha5' compile 'android.arch.persistence.room:runt
用户1665735
2018/06/20
2.3K0
学习|Android JetPack组件---ORM框架Room的使用
Room 持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。
Vaccae
2020/05/14
1.1K0
Android Room 持久化库
这是一篇自己从Android开发文档中翻译来的关于Room 的文档。哪里不对,欢迎纠错 Room 持久化库 Room持久性库提供了SQLite的抽象层,以便在充分利用SQLite的同时允许流畅的数据库访问。 该库可帮助你在设备上创建应用程序的缓存数据,这样不管设备是否联网都能看到数据。 摘自 Room Persistence Library 使用 Room 在本地保存数据 原文地址 https://developer.android.com/training/data-storage/room/index.
佛系编码
2018/05/22
4.1K0
Android — Room 数据库跳跃式升级(Migration)
前言 在平时的开发时,数据库的升级并不总是按部就班的从 version: 1->2,2->3,3->4。总是会出现 version:1->3,或 2->4 的情况。这时候我们又该怎么办呢? 方法很简单。当用户升级 APP 时,我们替用户升级数据库版本。 具体做法: version:1->2 static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQ
code_horse
2018/07/02
2.2K0
安卓软件开发:理解Room数据库和上手
Room 是SQLite的一个抽象层,解决了原生SQLite操作繁琐、易出错的问题。通过编译时检查、注解处理、数据访问对象(DAO)等机制,帮助开发者轻松管理和操作数据库。
Nimyears
2024/10/05
5780
Android Room数据库使用
  Room数据库是Google的JitPack组件中的一个,推出已经有一段时间了,现在的使用者也越来越多,Room是一个轻量级的ORM(Object Relational Mapping:对象关系映射)数据库。本质上就是对Android原生的SQLite的封装,只不过使用起来比原生简单,就好像一些开源库GreenDao、LitePal、OrmLite等,都是对Android SQLite的再次封装。
晨曦_LLW
2021/08/25
8050
Room 中的数据库自动迁移功能
自 2.4.0-alpha01 版本开始,Room 库里新加入了自动迁移的功能,这让数据库迁移的实现变得更简单。以往每当您的数据库 schema 发生变化时,您都必须实现一个 Migration 类,并将实际变化告知 Room,且多数情况下均涉及编写和执行复杂的 SQL 查询。
Android 开发者
2022/03/09
1.4K0
推荐阅读
【Jetpack】Room 预填充数据 ( 安装 DB Browser for SQLite 工具 | 创建数据库文件 | 应用中设预填充数据对应的数据库文件 | 预填充数据库表字段属性必须一致 )
7010
【Jetpack】使用 Room 中的 Migration 升级数据库异常处理 ( 多个数据库版本的迁移 | fallbackToDestructiveMigration() 函数处理升级异常 )
6430
【Jetpack】使用 Room Migration 升级数据库并导出 Schema 文件 ( Schema 文件简介 | 生成 Schema 文件配置 | 生成 Schema 文件过程 )
4440
【Jetpack】使用 Room 中的 Migration 升级数据库 ( 修改 Entity 实体类 - 更改数据模型 | 创建 Migration 迁移类 | 修改数据库版本 | 代码示例 )
1.5K0
Jetpack组件之Room
2K0
【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 )
5650
JetPack--Room数据库
1.5K0
【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )
1.1K0
Jetpack之Room的使用,结合Flow
1.2K0
Jetpack Room使用
3620
Android—Room 数据库迁移(Migration)
2.8K1
Android Room数据库版本迁移的实战
2K0
Android的room数据库使用小结(kotlin)
3.3K0
room的使用-以demo为例
2.3K0
学习|Android JetPack组件---ORM框架Room的使用
1.1K0
Android Room 持久化库
4.1K0
Android — Room 数据库跳跃式升级(Migration)
2.2K0
安卓软件开发:理解Room数据库和上手
5780
Android Room数据库使用
8050
Room 中的数据库自动迁移功能
1.4K0
相关推荐
【Jetpack】Room 预填充数据 ( 安装 DB Browser for SQLite 工具 | 创建数据库文件 | 应用中设预填充数据对应的数据库文件 | 预填充数据库表字段属性必须一致 )
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验