Android学习之基础知识九 — 数据存储(持久化技术)之SQLite数据库存储
前面一讲介绍了数据持久化技术的前两种:文件存储、SharedPreferences存储。下面介绍第三种技术:SQLite数据库存储
一、SQLite数据库存储
SQLite数据库是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百KB的内存就足够了,因而特别适合在移动设备上使用。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务,所以只要你以前使用过其他的关系型数据库,就能很快上手。而SQLite又比一般的数据库要简单的得多,它甚至不用设置用户名和密码就可以使用。Android正是把这个功能极为强大的数据库嵌入到了系统当中,成为了Android系统的内置数据库,使得本地持久化的功能有了一次质的飞跃。
前面我们所学的文件存储和SharedPreferences存储毕竟只适用于保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据的时候,这两种存储方式就很难应付了,这时候就需要使用到SQLite数据库。
1.1、创建数据库(SQLiteOpenHelper帮助类)
Android为了让我们更加方便地管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类我们可以非常简单的对数据库进行创建和升级。下面就来介绍一下SQLiteOpenHelper的基本用法。
1、首先需要知道SQLiteOpenHelper是一个抽象类,这意味着如果我们想要使用它的话,就需要创建一个自己的帮助类去继承它,SQLiteOpenHelper中有两个抽象方法,分别是:onCreate()方法和 onUpgrade()方法,我们必须在自己的帮助类中重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑。
2、SQLiteOpenHelper中还有两个非常重要的实例方法:getReadableDatabase()和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已经存在则直接打开,否则创建一个新的数据库),并返回一个对数据库进行读写操作的对象,不同的是,当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase()方法则将出现异常。
3、SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收4个参数,第一个参数是Context,这个没什么好说的,必须要有它才能对数据库进行操作;第二个参数是数据库名,创建数据库时使用的就是这里指定的名称;第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传入null;第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。构建出SQLiteOpenHelper的实例后,再调用它的:getReadableDatabase()或getWritableDatabase()方法就能创建数据库了,数据库文件会存放在:/data/data/程序包名/databases/目录下。此时,重写的onCreate()方法也会得到执行,所以通常会在这里去处理一些创建表的逻辑。
接下来我们就通过实际的例子来直观的体会一下SQLiteOpenHelper的用法吧。
这里我们希望创建一个名为BookStore.db的数据库,然后在这个数据库中新建一张Book表,表中有id(主键)、作者、价格、页数和书名等列,创建数据库表当然还是需要用建表语句的,Book表的建表语句如下所示:
SQLite不像其他数据库拥有众多复杂的数据类型,它的数据类型很简单,integer表示整型,real表示浮点型,text表示文本类型,blob表示二进制类型。另外我们还使用了primary key将id设置为主键,并用autoincrement关键字表示id列是自增长的。
然后我们开始写代码:
第一步:新建MyDatabaseHelper类继承SQLiteOpenHelper
第二步:设置一个按钮,用于实现点击按钮创建数据库和建表的功能
第三步:在MainActivity中实现数据库和表的创建
第四步:运行程序,点击按钮,弹出一个创建成功的Toast提示,说明数据库和表我们都已经创建完成了。
数据库和表都创建完成后,我们知道它是保存在:/data/data/com.workspace.hh.databasetest/databases目录下,如果还是使用File Explorer打开,我们只会看到一个BookStore.db文件,看不到Book表,这里我们换一个打开方式来查看数据库和Book表,就是使用adb shell来对数据库和表的创建情况进行检测。
adb是Android SDK中自带的一个调试工具,使用这个工具可以直接对连接在电脑上的手机或模拟器进行调试操作,它存放在sdk的platform-tools目录下,如果想要在命令行中使用这个工具,就需要先把它的路径配置到环境变量中。打开计算机 ---> 属性 ---> 高级系统设置 ---> 环境变量,然后在系统变量中找到Path并点击编辑,将platform-tools目录配置进去,如图所示:
配置完成后,就可以使用adb工具了:
(1)打开Android Studio中的Terminal工具:
(2)输入:adb shell,回车,进入到设备的控制台
(3)使用cd命令进入到db文件的目录:
(4)使用:ls命令来查看该目录里的文件:该目录下出现了两个数据库文件,一个正是我们的创建的BookStore.db,而另外一个BookStore.db-journal则是为了让数据库能够支持事务而产生的临时日志文件,通常情况下这个文件的大小都是0字节。
(5)借助sqlite命令来打开数据库:sqlite3 BookStore.db
(6)打开数据库后,就可以对这个数据库中的表进行管理了,首先我们看一下数据库中有哪些表:(.table)
可以看到数据库中有两张表,android_metadata表示每个数据库中都会自动生成的,不用管它,而另外一张book表就是我们创建的了。
(7)通过(.schema)命令来查看它们的建表语句:从建表语句中我们可以看出,数据库和表已经创建完成了。
(8)通过(.exit)或(.quit)命令退出数据库的编辑,然后再通过(exit)命令退出设备的控制台
1.2、升级数据库
在上面MyDatabaseHelper中还保留了一个:onUpgrade()方法,这个方法就是用于对数据库进行升级的,它在整个数据库的管理工作中起着非常重要的作用。目前DatabaseTest项目中已经存在一张Book表用于存放书的各种详细数据,接着我们再添加一张Category表用于记录图书的分类,Category表中有id(主键)、分类名个分类代码这几列,建表语句如下:
现在我们开始在代码中进行建表:
第一步:修改MyDatabaseHelper中的代码:
第二步:要执行:onUpgrade()方法,只需要输入一个比当前数据库的版本号大的版本号就行了
第三步:运行程序,点击按钮,我们看到有Toast提示弹出,接着我们检查数据库中是否成功创建了Category表,发现建表成功。
1.3、添加数据
我们对数据库的操纵无非就4种:CRUD,即:Create添加、Retrieve查询、Update更新、Delete删除。每一种操作都各自对应了一种SQL命令:添加用insert、查询用select、更新用update、删除用delete;Android提供了一系列的辅助方法,使得在Android中即使不去编写SQL语句,也能轻松完成所有的CRUD操作。
前面我们已经知道,调用SQLiteOpenHelper的:getReadableDatabase()或getWritableDatabase()方法是可以用于创建和升级数据库的,不仅如此,这两个方法还都会返回一个SQLiteDatabase对象,借助这个对象我们就可以对数据进行CRUD操作了。
SQLiteDatabase中提供了一个:insert()方法,这个方法就是专门用于添加数据的,它接收3个参数,第一个参数是表名,向哪个表添加数据,就是传入哪个表的名字;第二个参数是用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般我们用不到这个功能,直接传入null即可;第三个参数是一个ContentValues对象,它提供一系列的:put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。
下面就提高例子来亲自体验一下添加数据的操作:
第一步:创建一个按钮,通过点击按钮来添加数据
第二步:在MainActivity中实现添加数据的操作:
第三步:运行程序,看到有添加数据成功的提示信息,然后通过:(select * from book;)查询语句查看添加的两条数据(注意查询语句后面有分号)
1.4、更新数据
SQLiteDatabase中也提供了一个非常好用的:update()方法,用于对数据进行更新,这个方法接收4个参数,第一个参数个insert()方法一样,也是表名,指定去更新哪张表里的数据。第二个参数是ContentValues对象,要把更新的数据在这里组装进去。第三、第四个参数用于约束更新某一行或某几行中的数据,不指定的话默认就是更新所有行。
第一步:创建一个按钮,通过点击按钮实现数据更新
第二步:在MainActivity中实现业务逻辑
第三步:运行程序,点击按钮,在Terminal中查看是否更新成功
1.5、删除数据
SQLiteDatabase中提供了一个:delete()方法,专门用于删除数据,这个方法接收三个参数,第一个参数仍然是表名,第二、三个参数又是用于约束删除某一行或几行的数据,不指定的话默认就是删除所有行。
第一步:添加一个删除按钮,通过点击按钮来删除数据
第二步:在MainActivity中实现功能
第三步:运行程序,点击按钮,然后查看book表中的数据是否被删除,从查询的数据中,我们可以看出,页数为899的“The mental of Java”这本书已经被删除。
1.6、查询数据
SQLite的全称是:Structured Query Language,翻译成中文就是结构化查询语言,它的大部分功能都体现在“查”这个字上,而“增删改”只是其中的一小部分功能。SQLiteDatabase中还提供了一个:query()方法用于对数据进行查询,这个方法的参数非常的复杂,最短的一个方法重载也需要传入7个参数,这7个参数的含义是:
第一个参数:表名,即我们希望在哪张表中查询数据
第二个参数:指定去哪儿查询哪几列,如果不指定则默认查询所有列
第三、四个参数:约束查询某一行或某几行的数据,不指定则默认查询所有行的数据
第五个参数:指定需要去group by的列,不指定则表示不对查询结果进行group by操作
第六个参数:对group by之后的数据进行进一步的过滤,不指定则表示不进行过滤
第七个参数:指定查询结果的排序方式,不指定则表示使用默认的排序方式。
具体的内容可参照下表:
虽然:query()方法的参数非常多,但是我们不必为每条查询语句都指定所有的参数,多数情况下只需要传入少数几个参数就可以完成查询操作了。调用query()方法后会返回一个Cursor对象,查询到的所有数据都将从这个对象中取出。接下来我们就通过一个简单的例子来体验数据的查询操作:
第一步:创建一个按钮,通过点击按钮来查询数据
第二步:在MainActivity中实现功能逻辑
第三步:打印出查询到数据
1.7、使用SQL操作数据库
Android提供了一系列方法可以直接通过SQL来操作数据库,上面的CRUD操作可以用下面的SQL语句来完成:
除了查询语句的时候调用的是SQLiteDatabase的:rawQuery()方法,其他操作都是调用:execSQL()方法。
Android学习之基础知识九 — 数据存储(持久化技术)之SQLite数据库存储的更多相关文章
- Android学习之基础知识九—数据存储(持久化技术)
数据持久化是将那些内存中的瞬时数据保存到存储设备,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失. Android系统中主要提供了3种方式用于简单地实现数据持久化功能:文件存储.SharedP ...
- Android学习之基础知识九 — 数据存储(持久化技术)之使用LitePal操作数据库
上一节学习了使用SQLiteDatabase来操作SQLite数据库的方法,接下来我们开始接触第一个开源库:LitePal.LitePal是一款开源的Android数据库框架,它采用了对象关系映射(O ...
- Android中数据存储(三)——SQLite数据库存储数据
当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式 Android 的数据存储有5种方式: 1. Share ...
- Android学习之基础知识十三 — 四大组件之服务详解第一讲
一.服务是什么 服务(Service)是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用户交互而且还要求长期运行的任务.服务的运行不依赖于任何用户界面,即使程序被切换到后台, ...
- Android学习之基础知识一
一.Android的系统架构: 1.Linux内核层:提供Android硬件的各种驱动(显示驱动,音频驱动,蓝牙驱动,WiFi驱动等等) 2.系统运行库层:提供各种特性支持(数据库支持,绘图支持,浏览 ...
- Android学习之基础知识四-Activity活动4讲(Intent传递数据)
Intent除了可以开启一个活动,还能在启动活动的时候传递数据,此时Intent相当于一个保存数据的库,我们先把数据保存在Intent中,然后再根据各个activity的需要从其中取出数据. 一.使 ...
- Android学习之基础知识十五 — 最佳UI体验(Material Design实战)
一.前言 长久以来,大多数人都认为Android系统的UI并不美观,至少没有iOS系统的美观.以至于很多IT公司在进行应用界面设计的时候,为了保证双平台的统一性,强制要求Android端的界面风格必须 ...
- Android学习之基础知识十一 —运用手机多媒体
一.使用通知(Notification) 通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助 ...
- Android学习之基础知识十—内容提供器(Content Provider)
一.跨程序共享数据——内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能 ...
随机推荐
- 设计模式之迭代器模式(Iterator)
迭代器在STL运用广泛,类似容器的迭代已经成为其重要特性,而迭代器模式则是利用迭代器概念进行的抽象运用,迭代器模式运用广泛和有用,因为其能够不考虑数据的存储方式,而是直接面对数据进行迭代,也就是说我们 ...
- HttpHandler与HttpModule介绍
前言:作为一个开发人员,我们看过很多的关于开发的书,但是都是教我们"知其然",并没有教我们"知其所以然",我们开发web项目的过程中,当我们输完URL敲下回车就 ...
- Java抽象类和接口的比较
一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体 ...
- 移动端不利用HTML5和echarts开发一样可以实现大数据展示及炫酷统计系统(产品技术综合)
一.由于项目需要进行手机看板展示设计及开发展示效果图如下:
- Backbone.js学习之旅(一)
前言 刚到粑粑公司,就学习各种框架,进行各种开发,为了纪念挥泪的青春,只好写下…… 希望能合您胃口^_^!!! The First(文件准备) backobone 强制依赖于 underscore.j ...
- Python不可变对象
str是不变对象,而list是可变对象. 对于不可变对象,比如对str进行操作: # 对于list进行操作,list内部的内容是会变化的: >>> a = ['c', 'b', 'a ...
- SVN——Couldn't perform atomic initialization
前言 今天早上刚刚打开我的电脑,就被李总他们告知不能正确用SVN从服务器上下载代码了,然后看问题吧.问题其实也是本文的标题,并不难解决,写下来留个记录,顺便也算是一种分享.问题截图如下: 造 ...
- linux服务器系统盘坏且系统盘为软raid的修复方法
1 需要换新盘的情况 1.1 一块盘grub损坏修复 一块盘grub损坏修复(可通过另一块盘进入系统的情况).更换硬盘的方式,可以热插拔,也可以服务器断电后更换,但如果是热插拔,可能会导致盘符变更.坏 ...
- jQuery 实现图片动画代码
向下移动动画 $(".image").click(function(){ $(this).animate({height:'0px'}) }); <!doctype html ...
- MySQL复制ERROR 1794 (HY000): Slave is not configured or failed to initialize properly.
ERROR 1794 (HY000): Slave is not configured or failed to initialize properly. You must at least set ...