数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆算法来操作数据结构。
android系统集成了一个轻量级的关系型数据库:SQLite,从本质上讲,SQLite数据库在底层其实就是一个数据库文件,当我们打开SQLite数据库时,其实只是打开与之对应的数据库文件进行读写,所以说SQLite数据库的操作本质上只是一种更为便捷的文件操作。android系统中与SQLite数据库相关的类主要有三个:
SQLiteDatabase
SQLiteOpenHelper
Cursor
现分别对其一一做介绍:
1 SQLiteDatabase:
在应用程序中,我们无法通过sqliteshell直接输入命令来操作数据库,所以android系统提供了SQLiteDatabase类,该类提供的大量的API来操控SQLite数据库,每一个SQLiteDatabase的实例就代表了一个数据库(对应底层的一个数据库文件),一旦应用程序获得了SQLiteDatabase对象,就可以通过该对象来操作与之相对应的数据库。
Class Overview
Exposes methods to manage a SQLitedatabase.
SQLiteDatabase has methods to create, delete, execute SQLcommands, and perform other common database managementtasks.
Database names must be unique within an application, not acrossall applications.
SQLiteDatabase提供了许多方法用来管理SQLite数据库.主要的方法有:打开或创建数据库相关的方法:
static SQLiteDatabaseopenDatabase( String path, SQLiteDatabase.CursorFactory factory,
static SQLiteDatabaseopenOrCreateDatabase( String path, SQLiteDatabase.CursorFactory factory)
static SQLiteDatabaseopenOrCreateDatabase( File file, SQLiteDatabase.CursorFactory factory)
path:代表了要打开数据库文件。
factory: an optional factory class that is called to instantiate acursor when query is called,
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 ,insertinto,delete from,update,分别代表数据库表的增删改和记录的增删改命令
void execSQL( Stringsql)用来执行无占位符的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 intoperson(name, age) values('安桌', 4)");
该sql语句用来向persron表中插入一行记录。但实际应用中, 语句中类似“安桌”这些参数值往往来自用户UI界面,如果把用户输入的内容原样组拼到上面的insert语句,当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ &”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。为决绝类似的问题,SQLiteDatabase提供voidexecSQL(String sql)方法,用来执行带占位符的sql语句。
除此之外SQLiteDatabase还提供一大堆诸如insert,delete,updata,query的方法。其实这些方法都可以通过执行sql语句来实现。之所以提供这些方法,主要是android考虑到部分开发者对sql语法不熟悉,所以提供了这些方法来帮助开发者操作SQLite数据库,对于熟悉sql语法的开发者而言,完全可以忽略此类方法。
有关SQLite的粗略介绍,可参见:
SQlite学习笔记
2 Cursor
Class Overview
This interface provides random read-writeaccess to the result set returned by a database query. Cursorimplementations are not required to be synchronized so code using aCursor from multiple threads should perform its own synchronizationwhen using the Cursor.
所以Curosr其实就是一个工具类,其用途就是用来访问数据库查询语句的结果集。有过数据库基础的都知道:select语句的结果集其实就是一张表,由若干行和若干列组成,每一个行被称为记录,每一列被称为字段。
Cursor对象中包含一个记录指针,用来指向结果集中的某一行记录,Cur对象提供了一大堆的方法用来操作结果集,根据用途主要分两类:
1 与Cursor记录指针相关的方法:
abstract boolean moveToFirst()
abstract booleanmoveToLast()
abstract booleanmoveToNext()
abstract boolean moveToPrevious()//记录指针移到上一行
abstract boolean moveToPosition(int position)//记录指针移到指定行
abstract boolean move(intoffset)
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(intcolumnIndex)
其它都是getXxx()方法.
总结:如何通过Cursor对象读取结果集中的m行n的值呢?
其实非常简单,首先将Cursor的记录指针移动到m行,然后通过getXxx(n)方法读取指定字段的值即可。
遍历数据库结果集的的一般方法:
while(cursor.moveToNext())
{
}
3 SQLiteOpenHelper
Class Overview
A helper class to manage databasecreation and version management.
You create a subclass implementingonCreate(SQLiteDatabase)
,onUpgrade(SQLiteDatabase, int, int)
andoptionallyonOpen(SQLiteDatabase)
, and thisclass takes care of opening the database if it exists, creating itif it does not, and upgrading it as necessary. Transactions areused to make sure the database is always in a sensible state.
onUpgrade(SQLiteDatabase, int,int)方法,然后该类负责数据库的打开(如果数据库存在)和创建(如果数据库不存在),以及数据库的更新。
SQLiteOpenHelper常用方法介绍:
与打开关闭数据库相关的方法:
//以只读的方式打开数据库,并返回该数据库所对应的SQLiteDatabase对象。
SQLiteDatabase getWritableDatabase()//以读写的方式打开数据库,
并返回该数据库所对应的SQLiteDatabase对象。
synchronized void close()//关闭数据库
public abstract void onCreate( SQLiteDatabase db) //Calledwhen the database is created for the first time. This is where thecreation of tables and the initial population of the tables shouldhappen.
onCreate( SQLiteDatabasedb )方法是一个回调方法。 当应用程序第一次调用getReadableDatabase()或getWritableDatabase方法来打开数据库时,此时数据库不存在,于是系统就会回调该方法用来创建和初始化数据库的值。所以通常onCreate方法()用来执行数据库的建表,及数据初始化的地方。
onUpgrade( SQLiteDatabase db, intoldVersion, intnewVersion)方法同样也是一个回调方法。当我们在应用程序中创建SQLiteOpenHelper的实例且指定的数据库版本比原来的版本高时,系统就会回调该方法。
android应用程序中使用SQLite数据库的步骤:
1 第一步定义一个SQLiteOpenHelper的子类XxxDBHelper,并覆写OnCreate(SQLiteDatabasedb)方法。
2 根据需要在XxxDBHelper类中添加记录的增删改查方法。
3 在需要获取数据库数据的activity中创建XxxDBHelper的实例,并调用其方法操作数据库。