Android SQLite数据库版本升级的管理实现
发布时间 - 2026-01-11 03:06:05 点击率:次Android SQLite数据库版本升级的管理实现

我们知道在SQLiteOpenHelper的构造方法:
super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
中最后一个参数表示数据库的版本号.当新的版本号大于当前的version时会调用方法:
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
所以我们的重点是在该方法中实现SQLite数据库版本升级的管理
当我们项目刚开始的时候第一版SQLiteOpenHelper是这样写的:
package cc.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Demo描述:
* SQLite数据库版本升级的管理实现
*
* 参考资料:
* http://blog.csdn.net/guolin_blog
* Thank you very much
*/
public class DataBaseOpenHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME="test.db";
private static DataBaseOpenHelper mDataBaseOpenHelper;
public static final String CREATE_PERSON=
"create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))";
public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {
super(context, name, factory, version);
}
//注意:
//将DataBaseOpenHelper写成单例的.
//否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时
//会报错,提示数据库没有执行关闭操作
static synchronized DataBaseOpenHelper getDBInstance(Context context) {
if (mDataBaseOpenHelper == null) {
mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,1);
}
return mDataBaseOpenHelper;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_PERSON);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
在几天之后根据项目需求,需要添加一张student表,于是DataBaseOpenHelper就出现了第二版:
package cc.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseOpenHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME="test.db";
private static DataBaseOpenHelper mDataBaseOpenHelper;
public static final String CREATE_PERSON=
"create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))";
public static final String CREATE_STUDENT=
"create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))";
public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {
super(context, name, factory, version);
}
//注意:
//将DataBaseOpenHelper写成单例的.
//否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时
//会报错,提示数据库没有执行关闭操作
static synchronized DataBaseOpenHelper getDBInstance(Context context) {
if (mDataBaseOpenHelper == null) {
//改动1
mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,2);
}
return mDataBaseOpenHelper;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_PERSON);
//改动2
db.execSQL(CREATE_STUDENT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//改动3
switch (oldVersion) {
case 1:
db.execSQL(CREATE_STUDENT);
default:
}
}
}
较版本一在版本二中有三处修改的地方:
1 版本号变成了2
2 在onCreate()方法中添加了代码db.execSQL(CREATE_STUDENT);创建student表
因为有的用户根本就没有第一版本的APP,直接从市场下载了第二版本的App。所以当然会执行onCreate()而不会执行onUpgrade()
3 在onUpgrade()做了处理:当oldVersion为1时调用db.execSQL(CREATE_STUDENT);创建student表
因为有的用户手机上本来就有第一版本的APP,所以在App升级到第二版本时会执行onUpgrade(),不会执行onCreate()
通过这样的处理使得不同的情况下使用第二版APP时都会生成student表
又过了一个月,根据项目变更,需要给person表添加一个字段genderid,于是DataBaseOpenHelper就出现了第三版:
package cc.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseOpenHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME="test.db";
private static DataBaseOpenHelper mDataBaseOpenHelper;
//改动1
public static final String CREATE_PERSON=
"create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12)),genderid integer)";
public static final String ALTER_PERSON="alter table person add column genderid integer";
public static final String CREATE_STUDENT=
"create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))";
public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) {
super(context, name, factory, version);
}
//注意:
//将DataBaseOpenHelper写成单例的.
//否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时
//会报错,提示数据库没有执行关闭操作
static synchronized DataBaseOpenHelper getDBInstance(Context context) {
if (mDataBaseOpenHelper == null) {
//改动2
mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,3);
}
return mDataBaseOpenHelper;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_PERSON);
db.execSQL(CREATE_STUDENT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(CREATE_STUDENT);
//改动3
case 2:
db.execSQL(ALTER_PERSON);
default:
}
}
}
较版本二在版本三中有三处修改的地方:
1 改变了CREATE_PERSON语句,在改语句中增加了一个字段genderid
和前面的描述类似,有的用户第一次安装该APP时就直接下载了第三版
2 修改版本号为3
应对了用户从第一版本或者第二版本升级到第三版本的情况(见下分析)
3 在onUpgrade()方法中)做了处理:当oldVersion为2时调用 db.execSQL(ALTER_PERSON);修改person表,增加genderid字段
应对了用户从第二版本升级到第三版本的情况(见下分析)
注意一个问题:为什么这里的switch语句在每个case中没有break???
这是为了保证跨版本升级的时候每次数据库的升级都会执行到。
比如从第二版升级到第三版本,那么case 2会被执行。
比如从第一版直接升级到第三版本,那么case 1肯定会被调用,由于没有break所以会穿透switch语句又执行case 2语句继续升级,从而保证了数据的所有版本中的升级都会被执行到。
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Android
# SQLite数据库版本升级
# 数据库的管理升级问题
# Android 通过SQLite数据库实现数据存储管理
# Android利用Badge组件实现未读消息小红点
# Android开发之BottomSheetDialog组件的使用
# Android音视频开发只硬件解码组件MediaCodec讲解
# Android硬件解码组件MediaCodec使用教程
# android轻量级无侵入式管理数据库自动升级组件
# 升级到
# 报错
# 第三版
# 出现了
# 三处
# 这是
# 对了
# 是在
# 就有
# 是这样
# 如有
# 一个月
# 几天
# 中有
# 希望能
# 刚开始
# 时就
# 当我们
# 一个问题
# 谢谢大家
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在云虚拟主机上快速搭建个人网站?
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
米侠浏览器网页背景异常怎么办 米侠显示修复
iOS正则表达式验证手机号、邮箱、身份证号等
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
Java垃圾回收器的方法和原理总结
如何快速搭建高效简练网站?
高端企业智能建站程序:SEO优化与响应式模板定制开发
Windows Hello人脸识别突然无法使用
Laravel如何创建自定义Facades?(详细步骤)
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
如何用VPS主机快速搭建个人网站?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
微信小程序 HTTPS报错整理常见问题及解决方案
浅谈redis在项目中的应用
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
Laravel怎么在Blade中安全地输出原始HTML内容
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
Laravel如何实现本地化和多语言支持?(i18n教程)
个人摄影网站制作流程,摄影爱好者都去什么网站?
如何快速搭建高效WAP手机网站吸引移动用户?
实例解析angularjs的filter过滤器
制作企业网站建设方案,怎样建设一个公司网站?
php 三元运算符实例详细介绍
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
昵图网官方站入口 昵图网素材图库官网入口
如何撰写建站申请书?关键要点有哪些?
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
零基础网站服务器架设实战:轻量应用与域名解析配置指南
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
文字头像制作网站推荐软件,醒图能自动配文字吗?
高性价比服务器租赁——企业级配置与24小时运维服务
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
详解MySQL数据库的安装与密码配置
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
QQ浏览器网页版登录入口 个人中心在线进入
如何用y主机助手快速搭建网站?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
Linux后台任务运行方法_nohup与&使用技巧【技巧】
Laravel如何实现API速率限制?(Rate Limiting教程)
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
如何在建站宝盒中设置产品搜索功能?
linux写shell需要注意的问题(必看)
使用豆包 AI 辅助进行简单网页 HTML 结构设计
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
iOS UIView常见属性方法小结
想要更高端的建设网站,这些原则一定要坚持!

