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

这篇具有很好参考价值的文章主要介绍了【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、销毁 和 重建策略



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

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

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


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

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




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




1、创建 Migration 迁移类 - 重点


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

  • 【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )
  • 【Jetpack】使用 Room 中的 Migration 升级数据库 ( 修改 Entity 实体类 - 更改数据模型 | 创建 Migration 迁移类 | 修改数据库版本 | 代码示例 )

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

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

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

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

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


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

  • 首先 , 创建一张 符合 新数据库表结构 的 临时数据库表;
                // 创新临时数据库
                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")

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

最终定义的 Migration 为 :

        /**
         * 数据库版本 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 迁移类 ;

        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 ;

@Database(entities = [Student::class], version = 4, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {

4、修改实体类数据类型


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

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

修改为 :

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




三、完整代码示例



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


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


RoomDatabase 数据库类完整代码

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 实体类完整代码

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 的应用 , 输出结果如下 :

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)]

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


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


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

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

RoomDatabase 数据库类完整代码

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 实体类代码示例

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)"
    }
}

执行结果

执行结果如下 :

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)]

【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )文章来源地址https://www.toymoban.com/news/detail-478768.html

到了这里,关于【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(一)

    android 开发中,常见的数据存储的方式,有SharePreference、网络、Sqlite、MMKV、文件、 ContentProvider,其中,SharePreference、MMKV从简单的使用入手,到使用上的经验总结,最终我们借助于源码的深入阅读学习,对其原理也进行了深入的总结。但是,大家也发现了,数据库Sqlite有很多

    2023年04月10日
    浏览(45)
  • 【Jetpack】使用 Room Migration 升级数据库并导出 Schema 文件 ( Schema 文件简介 | 生成 Schema 文件配置 | 生成 Schema 文件过程 )

    使用 Room Migration 升级数据库 , 需要根据当前数据库版本和目标版本编写一系列 Migration 迁移类 , 并生成一个升级的 Schema 文件 , 该文件是 json 格式的文件 , 其中包含如下内容 : 版本信息 : 包括 当前版本 和 目标版本 ; 创建表语句 : 包括 新增的表的 定义 和 字段信息 ; 删除表语

    2024年02月09日
    浏览(57)
  • 【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 )

    对于 Room 框架 来说 , 使用 Java 语言 开发和使用 Kotlin 语言 开发 , 需要在 build.gradle 构建脚本 中进行不同的配置 , 主要有以下两个配置不同 : 应用的插件不同 ; 导入依赖库方式不同 ; 应用插件 应用的插件区别 : 如果使用 Java 语言开发 , 只需要导入 android 插件 ; 如果使用 Kotli

    2024年02月05日
    浏览(62)
  • Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

    目录 一、对象的创建方式 1. 使用构造方法 2. 使用工厂类方法 3. 使用工厂类的静态方法 二、对象的创建策略 1. 单例策略 2. 多例策略 三、对象的销毁时机 四、生命周期方法 1. 定义生命周期方法 2. 配置生命周期方法 3. 测试 五、获取Bean对象的方式 1. 通过id/name获取 2. 通过类

    2024年02月01日
    浏览(42)
  • android jetpack Room的基本使用(java)

    添加依赖 创建表 @Entity表示根据实体类创建数据表,如果有多个主键要使用primaryKeys = {} @ColumnInfo 表示在数据表中的名字 @Ignore 表示不在数据表创建此字段 @PrimaryKey 主键 创建DAO 每一个表都对应一个dao。 创建数据库 创建一个抽象类,设置要创建的数据表,数据版本,数据库名

    2024年02月07日
    浏览(41)
  • 【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )

    在上一篇博客 【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 ) 中 , 实现了 使用 Room 框架访问 Android 中的 SQLite 数据库的操作 , 每当数据库中的数据发生变化时 , 就需要开启线程 , 重新获

    2024年02月06日
    浏览(48)
  • 【数据库】如何利用Python中的petl将PostgreSQL中所有表的外键删除,迁移数据,再重建外键

    在数据库管理中,外键是一种重要的约束,用于确保数据的一致性和完整性。然而,在某些情况下,我们可能需要删除或修改外键。本文将介绍如何使用Python中的petl库将PostgreSQL中所有表的外键删除,迁移数据,并重新建立外键。 首先,我们需要安装petl和psycopg2库。在命令行

    2024年02月10日
    浏览(48)
  • 【Android】Room数据库的使用

    Room 是在 SQLite 的基础上推出的 Android 库,它是 Google 官方对数据库操作的推荐方式。使用 Room 可以更方便、高效地操作 SQLite 数据库。 添加依赖 在使用 Room 之前,需要在项目中添加 Room 相关的依赖。在 build.gradle 文件中添加以下依赖: 在上面的依赖中,我们添加了 room-runti

    2024年02月09日
    浏览(49)
  • Android使用kotlin+协程+room数据库的简单应用

    前言:一般主线程(UI线程)中是不能执行创建数据这些操作的,因为等待时间长。所以协程就是为了解决这个问题出现。 第一步:在模块级的build.gradle中引入   好了前期工作ok,正式编写room吧! 第二步:创建表实体  第三部:编写对应的Dao接口  第四步:创建数据库信息

    2024年02月13日
    浏览(50)
  • kotlin中使用Room数据库(包含升降级崩溃处理)

    目录 1.导入依赖库 2.数据实体类 3.数据访问对象 (DAO) 4.数据库类 5.调用DAO里面的“增、删、改、查”方法 6.数据库升降级处理 升级(保存数据库历史数据): 升级(不保存数据库历史数据): 降级(不保存数据库历史数据): 1.导入依赖库 2.数据实体类 3.数据访问对象 (D

    2024年02月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包