为什么要在应用程序中使用数据库?
数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆算法来操作数据结构。
android系统集成了一个轻量级的关系型数据库:SQLite,从本质上讲,SQLite数据库在底层其实就是一个数据库文件,当我们打开SQLite数据库时,其实只是打开与之对应的数据库文件进行读写,所以说SQLite数据库的操作本质上只是一种更为便捷的文件操作。android系统中与SQLite数据库相关的类主要有三个:
SQLiteDatabase
SQLiteOpenHelper
Cursor
现分别对其一一做介绍:
1 SQLiteDatabase:
在应用程序中,我们无法通过sqlite shell直接输入命令来操作数据库,所以android系统提供了SQLiteDatabase类,该类提供的大量的API来操控SQLite数据库,每一个SQLiteDatabase的实例就代表了一个数据库(对应底层的一个数据库文件),一旦应用程序获得了SQLiteDatabase对象,就可以通过该对象来操作与之相对应的数据库。
SQLiteDatabase提供了许多方法用来管理SQLite数据库.主要的方法有:
打开或创建数据库相关的方法:
static SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags)
static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)
static SQLiteDatabase openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory)
path:代表了要打开数据库文件。
factory: (一个可选的工厂类,当执行数据库查询语句时(即select语句),该参数会
被调用,用来实例化一个cursor对象,如果为null则表示使用系统默认的工厂来实例化cursor对象。
flag: 该参数的值可以是:OPEN_READWRITE
,OPEN_READONLY
,CREATE_IF_NECESSARY.分别代表读写,只读,
数据库不存在则创建。
2 操作数据库相关的方法:
void execSQL(String sql)
void execSQL(String sql, Object[] bindArgs)
Cursor rawQuery(String sql, String[] selectionArgs)
前两个方法用来执行无返回值的sql语句,比如create table ,drop table,alter table ,insert into,delete from,update,分别代表数据库表的增删改和记录的增删改命令
void execSQL(String sql)用来执行无占位符的sql语句,例如,如下两行代码将在数据库创建一个名为person_info的表:
String sql = "create table person_info (_id integer primary key, name text, age integer)";
db.execSQL(sql);
void execSQL(String sql, Object[] bindArgs)用来执行带占位符的sql语句,例如:
String sql = "insert into person_info (name,age) values(?,?)";
db.execSQL(sql,new Object[]{"孙悟空",500});
第一个参数sql代表了带占位符的sql语句。第二个参数指定占位符的值。
Cursor rawQuery(String sql, String[] selectionArgs)方法执行带占位符的数据库查询语句(即select语句),该方法返回一个Cursor对象用来遍历数据库查询语句的结果集(select语句的结果其实质就是一张表,select语句其实就是以一个或多个表作为输入,经过一些列处理,产生一个新的表作为输出而已。)
备注:为什么需要带占位符的sql语句?
例如:
db.execSQL("insert into person(name, age) values('安桌', 4)");
该sql语句用来向persron表中插入一行记录。但实际应用中, 语句中类似“安桌”这些参数值往往来自用户UI界面,如果把用户输入的内容原样组拼到上面的insert语句,当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。为决绝类似的问题,SQLiteDatabase提供void execSQL(String sql)方法,用来执行带占位符的sql语句。
除此之外SQLiteDatabase还提供一大堆诸如insert,delete,updata,query的方法。其实这些方法都可以通过执行sql语句来实现。之所以提供这些方法,主要是android考虑到部分开发者对sql语法不熟悉,所以提供了这些方法来帮助开发者操作SQLite数据库,对于熟悉sql语法的开发者而言,完全可以忽略此类方法。
有关SQLite的粗略介绍,可参见:
SQlite学习笔记
2 Cursor
所以Curosr其实就是一个工具类,其用途就是用来访问数据库查询语句的结果集。有过数据库基础的都知道:select语句的结果集其实就是一张表,由若干行和若干列组成,每一个行被称为记录,每一列被称为字段。
Cursor对象中包含一个记录指针,用来指向结果集中的某一行记录,Cur对象提供了一大堆的方法用来操作结果集,根据用途主要分两类:
1 与Cursor记录指针相关的方法:
abstract boolean moveToFirst() //记录指针移到第一行
abstract boolean moveToLast() //记录指针移到最后一行
abstract boolean moveToNext() //记录指针移到下一行
abstract boolean moveToPrevious() //记录指针移到上一行
abstract boolean moveToPosition(int position) //记录指针移到指定行
abstract boolean move(int offset) / /记录指针从当前位置向前或向后移动指定的行数,offset正数时向后移动,为负时向前移动。
abstract int getPosition() //返回记录指针当前位置 0代表第一行。.
abstract int getCount() //返回结果集中的记录总数。
备注:执行数据库查询语句返回的Cursor对象,其初始状态下记录指针指向的是第一行记录的前一个位置,通过调用getPosition()返回-1即可知。
2 其它一大堆都是用来读取指定字段值得方法getXxx().
abstract int getColumnCount() //返回结果集的列数(即结果集中每一行记录包含了多少个字段)
getColumnIndex(String columnName) //根据字段名返回该字段在结果集中的索引值(第一列为0,第二列为1,依次类推),如该字段不存在则返回-1.
getColumnName(int columnIndex) //根据索引值获取该字段的字段名。
abstract int getType(int columnIndex) //获得指定字段的类型,整形常量值FIELD_TYPE_BLOB,FIELD_TYPE_FLOAT,FIELD_TYPE_INTEGER,FIELD_TYPE_NULL,FIELD_TYPE_STRING 分别表示布尔类型,实数类型,整形,null,字符串类型。
其它都是getXxx()方法.
总结:如何通过Cursor对象读取结果集中的m行n的值呢?
其实非常简单,首先将Cursor的记录指针移动到m行,然后通过getXxx(n)方法读取指定字段的值即可。
遍历数据库结果集的的一般方法:
while(cursor.moveToNext())
{
//getXxx()读取指定列的值
}
3 SQLiteOpenHelper
SQLiteOpenHelper是一个助手类,用来管理数据库的创建和版本更新。SQLiteOpenHelper是一个抽象类,一般的用法是创建它的子类,并覆写onCreate(SQLiteDatabase db),onUpgrade(SQLiteDatabase, int, int)方法,然后该类负责数据库的打开(如果数据库存在)和创建(如果数据库不存在),以及数据库的更新。
SQLiteOpenHelper常用方法介绍:
与打开关闭数据库相关的方法:
//以只读的方式打开数据库,并返回该数据库所对应的SQLiteDatabase对象。
SQLiteDatabase getWritableDatabase() //以读写的方式打开数据库,并返回该数据库所对应的SQLiteDatabase对象。
synchronized void close() //关闭数据库
public abstract void onCreate(SQLiteDatabase db) //Called when the database is created for the first time. This is where the creation of tables and the initial population of the tables should happen.
onCreate(SQLiteDatabase db)方法是一个回调方法。当应用程序第一次调用getReadableDatabase()或getWritableDatabase方法来打开数据库时,此时数据库不存在,于是系统就会回调该方法用来创建和初始化数据库的值。所以通常onCreate方法()用来执行数据库的建表,及数据初始化的地方。
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法同样也是一个回调方法。当我们在应用程序中创建SQLiteOpenHelper的实例且指定的数据库版本比原来的版本高时,系统就会回调该方法。
android应用程序中使用SQLite数据库的步骤:
1 第一步定义一个SQLiteOpenHelper的子类XxxDBHelper,并覆写OnCreate(SQLiteDatabase db)方法。
2 根据需要在XxxDBHelper类中添加记录的增删改查方法。
3 在需要获取数据库数据的activity中创建XxxDBHelper的实例,并调用其方法操作数据库。