Android Room 数据库自动升级与迁移策略

前序

在 Android 应用开发中,Room 是 Google 提供的一个轻量级数据库框架,用于简化与 SQLite 的交互。在应用的迭代过程中,数据库的结构不可避免地会发生变化,因此,我们需要为数据库升级、降级以及数据迁移制定一套合适的策略。

本文将介绍 Room 数据库升级的几种场景和常见的处理方法,包括手动迁移和自动迁移的策略。

何时需要升级数据库版本号?

以下几种情况会导致数据库结构的变更,因此必须升级数据库版本号,并处理相应的迁移逻辑:

  1. 新增或删除表:当我们向数据库中添加或删除一张表时,必须升级版本号,并实现相应的迁移处理逻辑,以确保数据的一致性。

  2. 新增、删除或修改字段:当对表中的字段进行操作时,例如新增一个列、删除或重命名列,必须升级数据库版本号,同时处理好字段的迁移或初始化逻辑。

  3. 修改索引或约束:如果为某些字段添加索引,或者对字段的约束(如非空、唯一等)进行修改,同样需要升级版本号。

Room 数据库迁移策略

Room 提供了多种处理数据库迁移的方式,开发者可以根据项目需求选择合适的迁移策略:

1. fallbackToDestructiveMigration 删除数据库并重建

如果应用中的数据不重要,或者我们允许用户丢失数据库中的所有数据,可以使用 fallbackToDestructiveMigration 方法,该方法会在版本号发生变化时直接删除数据库并重建。

private static AppDatabase create(final Context context) {return Room.databaseBuilder(context,AppDatabase.class,"AppDatabase.db").fallbackToDestructiveMigration() // 自动删除并重建数据库.build();
}

注意:使用这种方式,所有的旧数据都会被删除,因此适合那些对数据持久性要求不高的场景。

2. addMigrations 自定义迁移逻辑

当需要保留用户数据时,可以通过自定义 Migration 来处理数据库结构变更。例如,给 user 表新增一个 testId 字段:

public static final Migration MIGRATION_2_3 = new Migration(2, 3) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { // 添加新字段并为其设置默认值database.execSQL("ALTER TABLE user ADD testId INTEGER DEFAULT 0 NOT NULL");} 
};

在数据库的 Room 实例构建时,将这个迁移添加到数据库构建器中:

private static AppDatabase create(final Context context) {return Room.databaseBuilder(context,AppDatabase.class,"AppDatabase.db").addMigrations(MIGRATION_2_3) // 自定义的迁移.build();
}

优点:这种方式可以确保在数据库结构变更时,用户的数据不会丢失,数据迁移可以按照开发者定义的逻辑进行。

3. Room 数据库自动迁移

从 Room 2.4 版本开始,支持自动迁移功能,能够根据数据库的 schema 文件自动生成迁移逻辑,简化了跨版本的升级工作。在自动迁移中,Room 会自动处理字段的增加和删除,开发者只需配置好数据库的 schemaLocation

步骤一:配置 room.schemaLocation

app/build.gradle 文件中配置注解处理器的参数,以便在编译时生成数据库的 schema 文件:

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

编译时会在配置的目录下生成数据库版本号对应的 json 文件 — 主要信息为数据库相关信息、相关表信息,自动升级会根据这些信息生成 Migration。升级方式类似于手动升级的方式。
所有的使用的版本号对应的 json 文件都不能缺少,否则对应版本的升级会出问题,若中途进行的数据库的自动化升级迁移,可考虑回退版本,编译成对应的 json 拷贝过来。

    app ├── build │   ├── libs │   ├── release │   └── schemas │       └── database.AppDatabase.json │       └── 2.json │       └──.json 
步骤二:配置自动迁移

Room 允许开发者定义跨版本的自动迁移,例如从 version 1 直接升级到 version 4

@Database(entities = {User.class}, version = 4,autoMigrations = {@AutoMigration(from = 1, to = 2),@AutoMigration(from = 2, to = 3),@AutoMigration(from = 3, to = 4),@AutoMigration(from = 1, to = 4)}
)
public abstract class AppDatabase extends RoomDatabase {
}

注意:在自动迁移中,字段的新增需要设置 defaultValue,否则会报错:

@ColumnInfo(defaultValue = "0") 
public int testId;

4. Room 跨版本升级与降级

Room 也支持顺序或跨版本的数据库升级。假设用户下载的是最新版本的应用(版本号为 4),而数据库版本从未升级(还停留在 version 1),Room 会自动依次执行从 version 1version 4 的所有迁移。

如果我们希望加快迁移速度,可以定义一个从 version 1 直接到 version 4 的迁移逻辑,并通过 addMigrations 方法添加:

public static final Migration MIGRATION_1_4 = new Migration(1, 4) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { // 自定义跨版本迁移逻辑database.execSQL("ALTER TABLE user ADD COLUMN testId INTEGER DDEDAQEFAULT 0 NOT NULL");database.execSQL("ALTER TABLE user ADD COLUMN test INTEGER DEDAQ 0 NOT NULL");} 
};

添加迁移到 Room 实例:

db = Room.databaseBuilder(MyApplication.getInstance(), AppDatabase.class, "AppDatabase.db").addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4).fallbackToDestructiveMigration() // 防止没有匹配到的迁移时崩溃.build();

通过这种方式,用户可以直接从 version 1 升级到 version 4,避免了逐个版本的迁移。

总结

在 Android 应用的开发中,数据库的升级与迁移是不可避免的工作。Room 提供了灵活的数据库迁移机制,可以通过手动定义迁移、自动生成迁移,或在必要时重建数据库。开发者应根据应用的实际需求选择合适的升级方案,以确保用户数据的完整性和系统的稳定性。

  • 自动迁移:适用于简单字段的增加、删除等结构变化。
  • 自定义迁移:适合复杂的数据库操作,能够灵活应对各种数据库结构调整。
  • 重建数据库:适用于数据不重要或者允许丢失数据的场景。

通过合理的迁移策略,确保数据库的稳定升级,是提高应用质量的重要一环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/879644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

太阳能光伏板航拍红外图像缺陷分类数据集

太阳能光伏板航拍红外图像缺陷分类数据集。 数据集共包含11种不同的缺陷分类, 总共20000张图片, 可用来做基于深度学习的缺陷分类 近红外,黑白图像,图示经过可视化处理。 数据集名称 太阳能光伏板缺陷分类数据集(Sola…

三相可控整流电路 (三相半波,三相桥式)

目录 1. 三相半波整流电路 2. 三相桥式全控整流电路 三相可控整流电路利用三相交流电源,通过可控硅(晶闸管)将交流电整流为直流电。主要有两种常见类型:三相半波整流电路和三相桥式全控整流电路。 1. 三相半波整流电路 三相半波…

《沈阳体育学院学报》

《沈阳体育学院学报》创刊于1982年,是由沈阳体育学院主办,面向国内外公开发行的体育类学术期刊;国际标准刊号为ISSN 1004-0560,国内刊号为CN 21-1081/G8;双月刊,单月中旬出版。 《沈阳体育学院学报》是中文…

宝塔部署python项目

宝塔部署-python项目文章浏览阅读559次,点赞11次,收藏9次。在添加项目后,选择项目所在的路径,然后命令行启动主py文件。具体先看项目日志,根据日志在环境管理处下载包。首先下载项目需要的python版本。_宝塔部署python…

LabVIEW提高开发效率技巧----VI服务器和动态调用

VI服务器(VI Server)和动态调用是LabVIEW中的两个重要功能,可以有效提升程序的灵活性、模块化和可扩展性。通过这两者的结合,开发者可以在运行时动态加载和调用VI(虚拟仪器),实现更为复杂的应用…

C++和OpenGL实现3D游戏编程【目录】

欢迎来到zhooyu的专栏。 个人主页:【zhooyu】 文章专栏:【OpenGL实现3D游戏编程】 贝塞尔曲面演示: 贝塞尔曲面演示zhooyu 本专栏内容: 我们从游戏的角度出发,用C去了解一下游戏中的功能都是怎么实现的。这一切还是要…

基于yolov8的无人机检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的无人机检测系统是一项前沿技术,结合了YOLOv8深度学习模型的强大目标检测能力与无人机的灵活性。YOLOv8作为YOLO系列的最新版本,在检测精度和速度上均有显著提升,特别适用于复杂和高动态的场景。 该系统通过捕获实…

论文笔记:基于LLM和多轮学习的漫画零样本角色识别与说话人预测

整理了ACM MM2024 Zero-Shot Character Identification and Speaker Prediction in Comics via Iterative Multimodal Fusion)论文的阅读笔记 背景模型框架实现细节 实验数据集实验可视化消融实验 背景 最近读到一篇新文章,主要是做漫画中的零样本角色识…

pikachu下

CSRF(跨站请求伪造) CSRF(get) url变成了这样了,我们就可以新开个页面直接拿url去修改密码 http://pikachu-master/vul/csrf/csrfget/csrf_get_login.php?username1&password2&submitLogin CSRF(post) 这里只是请求的方式不同,…

HC-SR04超声波传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 ultrasonic.h文件 ultrasonic.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 HC-SR04超声波传感器是通过发送和接收超声波,利用时间差和声音传播速度…

带你深入了解C语言指针(四)

目录 前言一、回调函数是什么?二、qsort使用1.什么是qsort2.qsort函数的语法解析3.回顾冒泡排序4.使用qsort函数排序整型数据4.1 思路分析4.2 完整代码:4.3 总体逻辑展现 5.使用qsort函数排序结构数据5.1 strcmp( )函数5.2 思路分析5.2.1 按名字比较5.2.…

力扣每日一题 公交站间的距离

环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i 1) % n 的车站之间的距离。 环线上的公交车都可以按顺时针和逆时针的方向行驶。 返回乘客从出发点 start 到目…

C# 使用Socket通信,新建WinForm服务端、客户端程序

一、新建WinForm Socket服务端程序 注:rtbReceviceMsg为RichTextBox控件 服务端程序、界面 服务端代码 public partial class Form1 : Form {public Form1(){InitializeComponent();}public virtual void TriggerOnUpdateUI(string message){if (this.InvokeRequir…

Oracle发送邮件功能:配置自动化发信指南?

Oracle发送邮件服务设置方法?怎么用Oracle数据库发信? Oracle数据库作为企业级应用的核心,其内置的发送邮件功能为企业提供了强大的自动化工具。AokSend将详细介绍如何配置Oracle发送邮件功能,以实现自动化发信,从而提…

leetcode 2576.求出最多标记下标

2576.求出最多标记下标 题意: 解析: 数组长为 n n n,因为一次标记两个,所以数组中最多有 ⌊ n 2 ⌋ \lfloor \frac{n}{2}\rfloor ⌊2n​⌋ 对标记。 贪心的考虑,一个数 x 一定优先与满足 y ≥ 2 x y \ge 2x y≥2…

上海泗博EtherNet/IP转PROFIBUS DP网关EPS-320IP成都地铁项目应用案例

背景: 地铁,作为城市的活力脉搏,不仅是衔接城市生活的关键纽带,更是现代城市交通体系中不可或缺的核心组成部分。因此,确保地铁的稳定运行对任何一座城市都至关重要。 上海泗博自动化,作为与成都地铁项目合…

使用ENVI之辐射定标

将下载好的遥感影像导入遥感影像处理软件ENVI 5.6中 使用ENVI 5.6的Toolbox中的Radiometric Calibration工具 跳出的Date Input File界面中选中要进行辐射定标的文件选中 再在跳出的Radiometric Calibration界面中将Output Interleave改为BIL再点击Apply FLAASH Settings Soale…

【iOS】push和present的区别

【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中,我们经常性的会用到界面的一个切换的问题,这里我们需要理清…

网络(四)——HTTP协议

文章目录 认识urlurlencode和urldecodeHTTP协议格式HTTP的方法HTTP的状态码HTTP常见Header 虽然应用层的协议是由人为规定的,但是已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用. HTTP(超文本传输协议)就是其中之一…

适合骑行的开放式耳机哪个品牌好?四款开放式蓝牙耳机推荐

骑行时是否有必要佩戴耳机是一个需要权衡安全与便利的问题。因为虽然耳机能提供音乐、导航等功能,但也可能分散注意力,影响骑行安全。而且这也是需要看个人需求决定的,骑行戴耳机的需求是什么,我想大部分人应该就是为了接听电话&a…