企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 6.3.2 数据存储与访问之——又见SQLite数据库 ## 本节引言: > 学习完上一节,关于Android中的SQLite的基本操作,你就已经掌握了,而在本节我们将会学习 一些稍微高级一点的东西,数据库事务,怎么将大二进制数据存储到数据库中,以及版本升级时 数据库如何处理!好的,开始本节内容! ## 1.SQLite事务 ![](http://www.runoob.com/wp-content/uploads/2015/09/29572776.jpg) 简单点说就是:写在事务里的所有数据库操作都成功,事务提交,否则,事务回滚,就是回到前面 的状态——未执行数据库操作的时候!另外,前面我们也将了,在data/data/<包名>/database/目录 下除了有我们创建的db文件外,还有一个xxx.db-journal这个文件就是用来让数据库支持事务而 产生的 临时的日志文件! ## 2.SQLite存储大二进制文件 当然,一般我们很少往数据库中存储大二进制文件,比如图片,音频,视频等,对于这些我们一般 是存储文件路径,但总会有些奇葩的需求,某天你突然想把这些文件存到数据库里,下面我们以 图片为例子,将图片保存到SQLite中,以及读取SQLite中的图片! ![](http://www.runoob.com/wp-content/uploads/2015/09/83617087.jpg) ## 3.SimpleCursorAdapter绑定数据库数据 当然,这个玩玩可以,还是不建议使用,尽管用起来很简单! 其实在讲ContentProvider我们就使用过这个东西来绑定联系人列表!这里就不写实例了, 直接上核心代码!需要的自己捣鼓捣鼓就好了,另外,现在我们一般很少自己写数据库的东西 ,一般是通过第三方的框架:ormlite,greenDao等,在进阶部分,我们会再来学习~ ![](http://www.runoob.com/wp-content/uploads/2015/09/21347521.jpg) ## 4.数据库升级的一些集锦 PS:好吧,这一块我并没有做过,始终是项目经验不够,公司的产品都是定位类的,刚看过公司 项目,发现前人留下的代码是:onCreate()创建DB,然后onUpgrade()把前面的DB删掉,然后 再调用onCreate()方法!看了几个版本的代码,发现并没有数据库升级的操作...没得借鉴, 只能参考下别人的做法了,下面是小猪查阅资料后的一些归纳,如果有什么不对,欢迎指出, 可能有些第三方的框架已经弄好了这个,时间关系,就不慢慢去考究了!知道可以留言,谢谢! ### 1)什么是数据库版本升级?怎么升级法? > 答:假如我们开发了一款APP,里面用到了数据库,我们假定这个数据库版本为v1.0, 在这个版本,我们创建了一个x.db的数据库文件,我们通过onCreate()方法创建了第一个table, t_user,里面有两个字段:_id,user_id;后面我们想增加一个字段user_name,这个时候 我们就需要对数据库表的结构进行修改了,而我们可以把更新数据库的操作梵高onUpgrade() 方法中,我们只需要在实例化自定义SQLiteOpenHelper的时候,修改版本号,比如把1改成2 这样,就会自动调用onUpgrade()的方法了!另外,对于每个数据库版本我们都应该做好 相应的记录(文档),类似于下面这种: | 数据库版本 | andoid对应版本 | 内容 | | --- | --- | --- | | v1.0 | 1 | 第一个版本,包含两个字段... | | v1.1 | 2 | 数据保留,新增user_name字段 | ### 2)一些疑问以及相关解决方案 **①应用升级,数据库文件是否会删除?** > 答:不会!数据什么的都在! **②如果我想删除表中某个字段或者增加一个新的字段,原先的数据还在吗?** > 答:在的! **③你刚说的那种粗暴的更新数据库版本的方式,不保留数据的,可以贴下吗?** > 答:可以,这里用的是第三方的ormlite,你也可以自己写数据库创建以及删除的代码: ![](http://www.runoob.com/wp-content/uploads/2015/09/83955871.jpg) **④比如是这种,假如我们已经升级到第三个版本了,我们在第二个版本增加了一个表,** **然后第三个版本也增加了一个表,加入用户直接从第一个版本升级到第三个版本,这样** **没经过第二个版本,就没有增加的那个表,这可怎么破?** > 答:很简单,我们可以在onUpgrade()里写一个switch(),结构如下: > > ``` > public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, > int arg2, int arg3) { > switch(arg2){ > case 1: > db.execSQL(第一个版本的建表语句); > case 2: > db.execSQL(第二个版本的建表语句); > case 3: > db.execSQL(第三个版本的建表语句); > } > } > > ``` > > 细心的你可能发现这里并没有写break,这就对了,这是为了保证跨版本升级时,每次数据库 修改都能全部执行到!这样可以保证表结构都是最新的!另外不一定是建表语句,修改表结构 也可以哦! **⑤旧表的设计太糟糕,很多字段要改,改动太多,想建一个新表,但是表名要一样** **而且以前的一些数据要保存到新表中!** > 答:呵呵,给你跪了,当然,也有解决办法,下面说下思路: > > 1.将旧表改名成临时表: **ALTER TABLE User RENAME TO _temp_User;** > > 2.创建新表: **CREATE TABLE User (u_id INTEGER PRIMARY KEY,u_name VARCHAR(20),u_age VARCHAR(4));** > > 3.导入数据; **INSERT INTO User SELECT u_id,u_name,"18" FROM _temp_User;** //原表中没有的要自己设个默认值 > > 4.删除临时表; **DROP TABLE_temp_User;** ## 本节小结: > 好的,本节我们对SQLite的事务,大二进制存储,SimpleCursorAdapter以及数据库升级的 一些问题进行了探究,而关于SQLite的东西,我们暂时就学这么多,关于第三方的使用,以及 一些高深的话题,我们到进阶的时候再和大家一起去研究~本节就到这里,谢谢~