日期:2014-05-16  浏览次数:20498 次

关于SQLite数据库的那些事儿

?

一、基础知识

在Android平台上,集成了一个嵌入式关系型数据库——SQLite。SQLite第一个Alpha版本诞生于2000年5月。它是遵守ACID的关联式数据库管理系统,包含在一个相对小的C库中,同时是D.RichardHipp建立的公有领域项目。SQLite官方网站: http://www.sqlite.org/;SQLite中文社区:http://www.sqlite.com.cn/。

SQLite3支持NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上SQLite3也接受varchar(n)、char(n)、decimal(p,s)等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在INTEGER类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数,当向这种字段保存除整数以外的数据时,将会产生错误。 另外,SQLite在解析CREATE TABLE语句时,会忽略CREATE TABLE语句中跟在字段名后面的数据类型信息,如下面语句中会忽略name字段的类型信息:

CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))即使指定了字段的数据长度,该字段仍然可以保存超过指定长度的内容。

SQLite可以解析大部分标准SQL语句,如:

查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句

如:select * from person

? ? select * from person order by id desc

? ? select name from person group by name having count(*)>1

分页SQL与MySQL类似,下面SQL语句获取5条记录,跳过前面3条记录

select * from person limit 5 offset 3 或者 select * from person limit 3,5

插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values('孙小圣',3)

更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=' 孙小圣' where id=10

删除语句:delete from 表名 where 条件子句。如:delete from person where id=10

?

?

二、操作数据库

在Android系统里为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理。为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。

?

SQLiteOpenHelper类的getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。

?

①:编写实现SQLiteOpenHelper类的子类DBOpenHelper

必须显式调用父类的构造方法:super(context, DATABASE_NAME, null, DATABASE_VERSION);

参数2是数据库名称,例如"sxs",可以没有后缀名,也可以有,例如" sxs.db"。

参数3是游标工厂,可以设为null使用默认的游标工厂。

参数4是版本号,例如是"1"。

数据库的位置:/data/data/<package_name>/databases/ sxs.db

?

②:创建数据库表

在onCreate(SQLiteDatabase db)方法中添加如下代码:

db.execSQL("create table person(personid integer primary key autoincrement, name varchar(20))");

?

SQLiteDatabase sQLiteDatabase = DBOpenHelper.getWritableDatabase();//第一次调用该方法就会创建数据库

第一次调用getWritableDatabase()或getReadableDatabase()方法后,SQLiteOpenHelper会缓存当前的SQLiteDatabase实例,SQLiteDatabase实例正常情况下会维持数据库的打开状态,所以你不再需要SQLiteDatabase实例时,请及时调用close()方法释放资源。一旦SQLiteDatabase实例被缓存,多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例。

?

③:通过SQLiteDatabase进行增删改查。CRUD是指增加(Create)、查询(Retrieve)(重新得到数据)、更新(Update)和删除(Delete)几个单词的首字母简写。

第一种方式:SQLiteDatabase.execSQL(" ? ")、rawQuery(" ? ");

execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句;rawQuery()方法用于执行select语句。rawQuery()方法的第一个参数为select语句,第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,第二个参数设置为null。rawQuery()方法返回Cursor对象,Cursor是结果集游标,用于对结果集进行随机访问,Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。另外Cursor还有常用的moveToPrevious()方法(用于将游标从当前行移动到