当前位置:网站首页>Android原生数据库的基本使用和升级
Android原生数据库的基本使用和升级
2022-07-04 19:44:00 【Just_Paranoid】
android原生数据库使用
SQLiteOpenHelper:数据库的创建、更新的操作对象
SQLiteDatabase:执行数据的增删改查的操作对象
SQLiteStatement:SQL执行的操作对象
sqlite内部实现
插入:SQLiteStatement.executeInsert
更新、删除:SQLiteStatement.executeUpdateDelete
查询:SQLiteCursorDriver.query
性能优化
1、预编译SQL语句,重复的操作使用SQLiteStatement
2、使用事务,做数据更新操作时提高性能
3、及时关闭Cursor
4、耗时异步化
基本使用
//创建数据库:继承系统的SQLiteOpenHelper,在onCreate和onUpgrade中实现数据库的创建以及更新
public class MyDbHelper extends SQLiteOpenHelper {
private static final String TAG = "MyDbHelper";
private static final String DB_NAME = "my.db";
private static final int DB_VERSION = 1;
public MyDbHelper(@Nullable Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 创建数据库
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 更新数据库
}
}
//2.数据库管理:对数据库的操作使用单例进行管理,用于获取一个可读可写的SQLiteDatabase
public class MyDbManage {
private static MyDbManage myDbManage;
private final MyDbHelper myDbHelper;
private MyDbManage(Context context) {
myDbHelper = new MyDbHelper(context);
}
public static MyDbManage getInstance(Context context) {
if (myDbManage == null) {
synchronized (MyDbManage.class) {
if (myDbManage == null) {
myDbManage = new MyDbManage(context);
}
}
}
return myDbManage;
}
/** * 获取一个可写的数据库 * * @return SQLiteDatabase */
public SQLiteDatabase getWritableDatabase() {
return myDbHelper.getWritableDatabase();
}
}
//3.数据库操作:针对每个实体,建议单独创建操作数据的DAO,更方便维护
public class MyDaoSample {
public static final String TABLE_NAME = "user";// 表名
public static final String USER_NAME = "username";
public static final String AGE = "age";
public static final String SEX = "sex";
private static MyDaoSample myDaoSample;
private final SQLiteDatabase mDb;
private MyDaoSample() {
MyDbManage dbManage = MyDbManage.getInstance(CoreApplication.mApp);
mDb = dbManage.getWritableDatabase();
}
public static MyDaoSample getInstance() {
if (myDaoSample == null) {
synchronized (MyDaoSample.class) {
if (myDaoSample == null) {
myDaoSample = new MyDaoSample();
}
}
}
return myDaoSample;
}
public void insert() {
ContentValues values = new ContentValues();
values.put(USER_NAME, "susu");
values.put(AGE, 18);
mDb.beginTransaction();
mDb.insert(TABLE_NAME, null, values);
mDb.setTransactionSuccessful();
mDb.endTransaction();
}
}
Android原生数据库的升级更新OnUpgrade
注意点:
1.修改数据库版本号
2.重写OnUpgrade方法
//DBOpenHelper数据库类
public class DBOpenHelper extends SQLiteOpenHelper
//数据库版本号
private static final int DB_VERSION = 2;
//初始化
private DBOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
//升级数据库
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 1) {
db.beginTransaction();
try {
// upgrade note table column
db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_IS_TOP_ID + " int;");
db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_TOP_DATE_ID + " long;");
db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_IS_CONTAIN_VOICE_ID + " int;");
db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_PIC_PATH_ID + " text;");
// upgrade folder table column
db.execSQL("ALTER TABLE " + FOLDER_TABLE_NAME + " ADD COLUMN " + FOLDER_IS_TODO + " int;");
//insert default values
String travel = mContext.getString(R.string.folder_travel);
String life = mContext.getString(R.string.folder_life);
String work = mContext.getString(R.string.folder_work);
db.execSQL("INSERT INTO "
+ FOLDER_TABLE_NAME
+ " VALUES ('1','"+travel+"', '0', '0','0');");
db.execSQL("INSERT INTO "
+ FOLDER_TABLE_NAME
+ " VALUES ('2','"+life+"', '0', '0','0');");
db.execSQL("INSERT INTO "
+ FOLDER_TABLE_NAME
+ " VALUES ('3','"+work+"', '0', '0','0');");
// create todo table
db.execSQL(" CREATE TABLE IF NOT EXISTS " + TODO_TABLE_NAME + " ( "
+ ID + " integer primary key autoincrement , "
+ TODO_CONTENT + " text , "
+ TODO_IS_IMPORTANT + " int , "
+ TODO_TIME + " long , "
+ TODO_REPEAT + " int , "
+ TODO_IS_COMPLETE + " int , "
+ TODO_IS_DELAY + " int , "
+ TODO_IS_DELETED + " int , "
+ TODO_PARENT_FOLDER_ID + " int , "
+ TODO_DATE + " long);");
db.setVersion(DB_VERSION);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
}
// 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次)
public abstract void onCreate(SQLiteDatabase db);
// 如果数据库文件存在,会调用onUpgrade()方法升级数据库,并更新版本号。
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion);
OnCreate : 如果数据库文件不存在,SQLiteOpenHelper在创建数据库文件,打开数据库这个数据库后,调用onCreate()方法,在该方法中一般需要创建表、视图等组件。在创建前数据库一般是空的,因此不需要先删除数据库中相关的组件。
OnUpgrade : 当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。
新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。
需要对SQLite数据库的结构进行升级:
SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。
并且只能在表的末尾添加字段,比如,为 Student添加两个字段:
1 ALTER TABLE Student ADD COLUMN UserPhone VARCHAR;
2 ALTER TABLE Student ADD COLUMN UserNickName VARCHAR;
如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。
将表名改为临时表
ALTER TABLE Student RENAME TO __temp__Student;创建新表
CREATE TABLE Student (UserId VARCHAR(32) PRIMARY KEY ,UserName VARCHAR(32) NOT NULL ,UserAddress VARCHAR(16) NOT NULL);导入数据
INSERT INTO Student SELECT UserId, “”, UserAddress FROM __temp__Student;
或者
INSERT INTO Student() SELECT UserId, “”, UserAddress FROM __temp__Student;
- 注意 双引号”” 是用来补充原来不存在的数据的
- 删除临时表
DROP TABLE __temp__Student;
通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。
当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。
相关参考
https://blog.csdn.net/linglingchenchen/article/details/123632277
边栏推荐
- 企业数字化转型最佳实践案例:基于云的数字化平台系统安全措施简介与参考
- See how Tencent does interface automation testing
- ACM组合计数入门
- AP8022开关电源小家电ACDC芯片离线式开关电源IC
- Sword finger offer II 80-100 (continuous update)
- Alibaba testers use UI automated testing to achieve element positioning
- 【ISMB2022教程】图表示学习的精准医疗,哈佛大学Marinka Zitnik主讲,附87页ppt
- 九齐单片机NY8B062D单按键控制4种LED状态
- From automation to digital twins, what can Tupo do?
- LeetCode 7. 整数反转
猜你喜欢
Flet tutorial 05 outlinedbutton basic introduction (tutorial includes source code)
How does the computer save web pages to the desktop for use
Qt五子棋人机对战画棋子之QPainter的使用误区总结
Win11无法将值写入注册表项如何解决?
RFID仓库管理系统解决方案有哪些功能模块
Four traversal methods of binary tree, as well as the creation of binary tree from middle order to post order, pre order to middle order, pre order to post order, and sequence [specially created for t
工厂从自动化到数字孪生,图扑能干什么?
ICML 2022 | meta proposes a robust multi-objective Bayesian optimization method to effectively deal with input noise
面对同样复杂的测试任务为什么大老很快能梳理解决方案,阿里十年测试工程师道出其中的技巧
LeetCode+ 81 - 85 单调栈专题
随机推荐
How to adapt your games to different sizes of mobile screen
What is the development of block hash quiz game system? Hash quiz game system development (case mature)
[today in history] July 4: the first e-book came out; The inventor of magnetic stripe card was born; Palm computer pioneer was born
ACM组合计数入门
Leetcode+ 81 - 85 monotone stack topic
Some suggestions for interface design
太方便了,钉钉上就可完成代码发布审批啦!
Redis分布式锁的实现
go语言笔记(2)go一些简单运用
The problem of the maximum difference between the left and right maxima
hash 表的概念及应用
强化学习-学习笔记2 | 价值学习
Reinforcement learning - learning notes 2 | value learning
【ISMB2022教程】图表示学习的精准医疗,哈佛大学Marinka Zitnik主讲,附87页ppt
奏响青春的乐章
MySQL statement execution details
实操自动生成接口自动化测试用例
Win11怎么搜索无线显示器?Win11查找无线显示器设备的方法
企业数字化转型最佳实践案例:基于云的数字化平台系统安全措施简介与参考
Flet tutorial 06 basic introduction to textbutton (tutorial includes source code)