android app 数据库更新方案规范 - mindpin/knowledge-space-net-lib GitHub Wiki
流程描述
-
声明一个接口 IMigration,接口有一个 update 方法
-
每一个 migrate 声明成一个 java 类(M20140210xxxxxXxxXxxx.java)并实现 IMigration 接口(需要一个脚本生成 java 文件,包括类名和表示 migration 的编号的类变量)
- migration的生成脚本需要一个java类的文件模板(或者硬编码一个java类的模板字符串到脚本里)
- 根据当前时间(由日期/小时/分钟/秒拼装)生成migration编号和migration类名(如 2014/02/10/ 14:50:24 =>
{编号: 20140210145024, 类名: M20140210145024}
) - 运行脚本后根据模板在一个指定的包里(如
db.migrations
)生成最终的migration java文件(如: M20140210145024.java)
-
读取到 app中所有的 migrate java 类, 有两种思路:
- migration生成脚本维护一个migration列表文件,每次生成新的migration时在该文件末尾追加新生成的migration类名,并在代码中利用
((IMigration) Class.forName("db.migrations.M20140210145024").newInstance()).update();
的方式来一一获得对应的migration类实例并执行 - 利用反射获取某一package下得所有类, 比较简便的方法是利用google guava库里的ClassPath来获取,缺点是guava库本身体积较大,而且看其源代码里获取类名的过程io操作比较频繁
- migration生成脚本维护一个migration列表文件,每次生成新的migration时在该文件末尾追加新生成的migration类名,并在代码中利用
-
数据库中存在一个表(migrations)记录了已经运行过的 migrate 的编号,需要把所有的 migrate 和数据库中已经运行过的作比较,筛选出还没有运行过的 migrate ,并把筛选出来的 migrate 按照编号先后排序,并依此运行,运行成功的 migrate 把编号记录到 migrations 表中
流程图
需要进一步考虑的问题
- 读取所有 migrations 的方式有两种
- migration 统一声明到配置文件,通过读取这个配置文件来读取到所有 migration
- migration 类名声明 java annotation,通过反射的 annotation 相关API,读取到所有的 migration
- migration 出错时,如何进行错误处理