文章目录

  • 数据库迁移的引擎
    • SQLite API 都干了些啥
    • Room 都干了些啥
    • 迁移 SQLite API 代码 到 Room
      • 情景一:保持数据库版本不变 --- app崩溃
        • 第一步:尝试打开数据库
      • 情景二:版本更新了,但是没有提供迁移策略 --- app崩溃
        • 第一步:更新数据库版本从1(已经安装到设备上了)到2
      • 情景三:版本更新了,回退到破坏性迁移 --- 数据库数据被清空了
        • 第一步:尝试从版本1更新到版本2
        • 第二步:尝试重新打开数据库
      • 情景四:版本更新了,也提供了迁移策略 --- 数据健在
        • 第一步:尝试更新版本1到版本2
        • 第二步:尝试打开数据库
    • 简单的数据库架构发生改变,如何迁移?
    • 复杂的数据库架构发生改变,如何迁移?
    • 多版本数据库增量如何迁移?
    • 结论

这是一篇来自Android官方介绍Room迁移的文章,主要是最近公司项目处于快速迭代状态,数据库经常更新,数据迁移就成了一个大问题,这里也学习了一个Room官方对迁移的理解和实践。

首先需要配置一下:

dependencies {def room_version = "2.2.5"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor// optional - Kotlin Extensions and Coroutines support for Roomimplementation "androidx.room:room-ktx:$room_version"// optional - RxJava support for Roomimplementation "androidx.room:room-rxjava2:$room_version"// optional - Guava support for Room, including Optional and ListenableFutureimplementation "androidx.room:room-guava:$room_version"// Test helperstestImplementation "androidx.room:room-testing:$room_version"
}

原文地址为:地址

原文如下:

使用 SQLiteAPI 对数据库迁移总是觉得自己在拆炸弹,哪怕是错了一步,程序就在用户手中崩溃。但是你使用 Room 来处理数据库的操作,迁移就是是打开一个开关一样简单.

使用了 Room,如果你更改了 数据库的架构,但是没有更新数据库的版本,你的 app 就将崩溃。如果你更新了数据库版本,但是没有提供任何的 迁移策略,你的app会崩溃,或者你的数据库表被删除了、或者用户数据会丢失。不要靠瞎想在实现数据库的迁移。深入理解 Room,那么迁移你的数据库将会更有信息。


数据库迁移的引擎

SQLite API 都干了些啥

SQLite 数据库依靠 数据库版本来处理数据库架构的变化。更精确点,每次你新增、移除、修改你的数据库表时,你必须得增加数据库版本数字,然后更新 SQLiteOpenHelper.onUpgrade 方法。这就是告诉 SQLite 从旧版本迁移到新版本,需要做什么事情。
当你的 App 开始使用数据库时, SQLiteOpenHelper.onUpgrade 也将触发。当打开数据库时,SQLite 首先将会处理版本更新。

Room 都干了些啥

Room 提供了一个抽象层来来缓解 SQLite 的迁移,展现形式是以 Migration 类 来实现的。Migration 类定义了从指定版本迁移到另外一个版本的动作。Room 使用了它自己的 SQLiteOpenHelper 的实现,在 onUpgrade 方法中,将会触发你定义的迁移动作。
这里展示了当第一次进入数据将会发生的事情:

  1. Room 数据将会被建立
  2. SQLiteOpenHelper.onUpgrade 被调用,Room触发迁移动作
  3. 数据库被打开

如果你没有提供迁移策略,但是你却增加了数据库版本,你的app可能会被崩溃或者你的数据将会被丢失,至于产生的结果,基于我们将会谈到的情形。

在迁移中,一个很重要的点就是 identity hash String. Room 就是通过唯一这个 identity String 区分数据库的版本。当前的数据库中有个 configuration table 保存了 identity String. 如果不要太惊讶你查看数据库时会有一张 room_maste_table 表。

我们来做个简单的例子,有一个 user 的表,存在两列:

  1. ID ,int类型,同时也是主键
  2. 用户名,String类型的

user 表属于版本1数据库的一部分,通过 SQLiteOpenHelper API来实现的。
我们来想一下,如果用户已经使用了这个版本,此时你想用 Room 来管理数据库,我们来看一下 Room 怎么处理这些场景。


迁移 SQLite API 代码 到 Room

我们假设 User 实例代码、UserDao 和 data access object class 都创建完成了,我们注重于 UserDatabase 类,它继承自RoomDatabase:


@Database(entities = {User.class},version = 1}
public abstract class UserDatabase extends RoomDatabase
情景一:保持数据库版本不变 — app崩溃

如果我们保持数据库版本不变,直接运行我们的App,Room在背后所做的事情如下:

第一步:尝试打开数据库

比对数据库的identity值:当前的版本的 identity hash与在 room_master_table 中 identity hash比较。但是因为identity hash没有被存储,因此app 将会奔溃:

java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you’ve changed schema
but forgot to update the version number. You can simply fix this by increasing the version number.

如果你修改了数据库的架构,但是没有更新数据库的版本,Room 总会报 IllegalStateException。

我们听从它的意见,将版本修改为2:


@Database(entities = {User.class},version = 2}
public abstract class UserDatabase extends RoomDatabase
情景二:版本更新了,但是没有提供迁移策略 — app崩溃

我们按照以下步骤再次运行 Room:

第一步:更新数据库版本从1(已经安装到设备上了)到2

因为没有迁移策略,所以应用崩溃报 IllegalStateException.❌

java.lang.IllegalStateException: A migration from 1 to 2 is necessary.
Please provide a Migration in the builder or call fallbackToDestructiveMigration in the builder
in which case Room will re-create all of the tables.

如果你没有提供迁移策略,Room 就会报 IllegalStateException 异常

情景三:版本更新了,回退到破坏性迁移 — 数据库数据被清空了

如果你不想提供迁移策略,而且你特别指定了在更新数据库版本时,数据库数据将会被清空,那么调用fallbackToDestructiveMigration可以满足你的要求:

database = Room.databaseBuilder(context.getApplicationContext(),UsersDatabase.class, "Sample.db").fallbackToDestructiveMigration().build();

接下来我们再次运行,Room 将会做一下动作:

第一步:尝试从版本1更新到版本2

因为现在没有迁移策略,而且我们还设定了回退到破坏性迁移,那么所有的数据库表将会被删除掉,新的identity hash 将会被插入。

第二步:尝试重新打开数据库

因为当前版本的identity hash 和 插入的identity hash是同一个,数据库打开。✅

现在打开时,我们的app没有奔溃,但是我们丢失了所有数据。做这种操作时,先看看是不是真要这么操作

理解Room数据库的迁移(Migration)相关推荐

  1. Django(part33)--数据库的迁移

    学习笔记,仅供参考 数据库的迁移 我在学习一对多映射时,由于操作不慎,导致报错频频,现在,我就来解决这个问题,顺便学习一下迁移操作. 现在,我在第7次迁移时出错了,它的错误是这样的: pymysql. ...

  2. python脚本迁移数据库_Python迁移MySQL数据到MongoDB脚本

    MongoDB是一个文档数据库,在存储小文件方面存在天然优势.随着业务求的变化,需要将线上MySQL数据库中的行记录,导入到MongoDB中文档记录. 一.场景:线上MySQL数据库某表迁移到Mong ...

  3. sqldeveloper mysql迁移_通过SQL Developer工具将MySQL数据库内容迁移至Oracle的步骤

    通过SQL Developer工具将MySQL数据库内容迁移至Oracle的步骤 发布时间:2020-06-08 15:52:18 来源:51CTO 阅读:210 作者:三月 本篇文章给大家主要讲的是 ...

  4. (一)NET Core 项目中通过EF Core的Code First方式进行数据库的迁移

    EF Core 是现有EF库的修改版本,具有可扩展的,轻量级的和跨平台的支持.它支持关系型数据库和非关系型数据库.还支持"代码优先"或"数据库优先"方法作为编程 ...

  5. 总分第一!阿里云数据库应用迁移解决方案通过信通院首批最高级评测

    简介:6月25日,记者采访获悉,经中国信息通信研究院(以下简称"信通院")的严格测试评定,阿里云数据库应用迁移服务顺利通过了"数据库应用迁移服务能力"评测,总得 ...

  6. DSG-Oracle数据库在线迁移服务

    作为企业业务数据的核心组成部分,Oracle数据库系统往往扮演着极为重要的角色,它的中断通常会造成极为严重的后果,因此在关键业务中Oracle数据库系统的数据库版本升级.操作系统平台更换.服务器或磁盘 ...

  7. db2 linux 平台下迁移_Linux 下的 DB2数据库的迁移

    前言: DB2 Universal Database™(DB2 UDB) 有一对非常有用的工具,可以帮助您实现这种跨平台的备份与恢复功能. db2move 工具利用了 DB2 的数据移动工具(expo ...

  8. 阿里云PolarDB发布重大更新 支持Oracle等数据库一键迁移上云

    5月21日,阿里云PolarDB发布重大更新,提供传统数据库一键迁移上云能力,可以帮助企业将线下的MySQL.PostgreSQL和Oracle等数据库轻松上云,最快数小时内迁移完成.据估算,云上成本 ...

  9. 深度剖析数据库国产化迁移之路

    作者 | 吴夏,腾讯云 TDSQL 高级工程师 责编 | 唐小引 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDNnews) 随着国家有关部门近年来陆续出台相关政策指导文件,推 ...

  10. 阿里云PolarDB重大更新:两大技术突破,传统数据库一键迁移上云

    5月21日,阿里云PolarDB发布重大更新,提供传统数据库一键迁移上云能力,可以帮助企业将线下的MySQL.PostgreSQL和Oracle等数据库轻松上云,最快数小时内迁移完成.据估算,云上成本 ...

最新文章

  1. 【STM32 .Net MF开发板学习-25】LED数码管显示
  2. html退出登录_[实战小剧场servletamp;jsp] 用户登录及退出功能实现
  3. php要掌握的内容,入门PHPer需要掌握的哪些内容?
  4. 带你自学Python系列(十四):Python函数的用法(四)
  5. HTTPS加密传输过程
  6. gogs可以自动化部署吗_效率提升利器:你还害怕自动化部署吗?
  7. Python IDE集成开发工具
  8. ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus
  9. 自学数据科学机器学习,19个数学和统计学公开课推荐
  10. 博士后斯坦福大学计算机学院,美国斯坦福大学博士后职位
  11. Java编程题——打印“ X ”图形
  12. 使用U盘全新安装Mac OS X EI Capitan
  13. C#开发的3D图表控件,适用于winform项目
  14. Eclipse SVN提交代码ClientException异常解决
  15. 微信小程序初始化NPM
  16. 解绑ip linux,H3C 批量解绑 IP 地址绑定
  17. qt window release 打包的方法及常见问题,不同路径的差异
  18. java实现实体关系抽取
  19. centos7源代码编译安装heartbeat
  20. 解密openGauss DB4AI框架的内部机理

热门文章

  1. STM32时钟--基于正点原子STM32视频教程
  2. vba模拟鼠标点击_这些掌握了,你才敢说自己懂VBA
  3. jquery的一些小小实例
  4. 用js判断图片地址是否有效
  5. 基于PHP+Html+MySQL的网上手机商城系统
  6. ettercap dns投毒
  7. 【实践】关于智能蛇的三次尝试
  8. 两个for循环写出大小写字母表
  9. Ajax获得网页源文件
  10. 铁蛋白-AHLL纳米颗粒|人表皮生长因子-铁蛋白重链亚基纳米粒子(EGF-5Cys-FTH1)|铁蛋白颗粒包载氯霉素Chloramphenicol-Ferritin