安卓 SQLite
SQLite学习整理
当程序中需要的数据量较大,且需要进行大量数据的插入、更新、查询等操作时,如果再使用文件方式来保存数据就显得效率低下。这时需要使用关系型数据库来对数据进行存储。SQLite数据库作为轻量级的关系型数据库,且小巧易用、具备关系型数据库的各种优点,因此被广泛用于手机、MP3等各种资源受限设备中。
SQLite使用C语言编写,完全独立化,使用时不需要额外的设置。具有如下特点:
·支持大多数ANSI SQL92标准
·支持数据库事务
·数据库位于一个单独的文件内,方便管理
·内存消耗小,且运行速度快
·提供简单且易用的API
·支持最大2TB的数据库等。
SQLite的官方网站是:http://www.sqlite.org/
数据库基础概念
SQlite 通过文件来保存数据库,一个文件就是一个数据库。
数据库里又包含数个表格;
每个表格里面包含了多个记录;
每个记录由多个字段组成;
每个字段都有其对应的值;
每个值都可以指定类型。
数据库名称即文件名;表格有自己的名称;记录没有名称;每个字段都有名称。在SQlite中,记录没有顺序的概念,不存在第一、第二此类的概念;只能通过查询来获取满足条件的记录。我们通过执行SQL指令来操作数据库
SQLite的使用
与SQLite相关的操作API存放在android.database.sqlite包下。Android系统中创建及操作SQLite数据库有两种途径,一是直接通过SQLiteDatabase类的对象来进行,另一种是继承SQLiteOpenHelper类自定义的数据库处理类。
几个相关的类
·SQLiteDatabase 数据库访问类:执行对数据库的插入记录、查询记录等操作。
·SQLiteOpenHelper 抽象类:通过从此类继承实现用户类,来提供数据库打开、关闭等操作函数。
·SQLiteCursor 查询结构操作类:用来访问查询结果中的记录。
SQLiteDatabase类
这个类是数据库访问类,包含了数据库操作的API,通过调用这些API可以完成对数据库的操作,如添加表格、添加记录、删除记录、查询等。
·openOrCreateDatabase(。。。)静态方法,用来创建一个SQLite数据库文件,方法返回值为数据库SQLiteDatabase对象。有两个不同的重载方法,允许传入作为SQLite数据的File对象或是指定SQLite数据库所在的位置及数据库名。可以通过根据返回值是否为null来判断数据库创建或打开成功。数据库默认在/data/data/<程序包名>/databases/这个目录下
·close()关闭数据库。当不再使用时可以调用这个方法关闭数据库
·deleteDatabase( DATABASE_NAME)删除数据库名为DATABASE_NAME的数据库。根据返回值判断是否删除成功
·execSQL执行SQL语句。这个方法不能执行选择语句或者其他带返回值的SQL。
·beginTransaction启动事务
·setTransactionSuccessful设置事务成功标志
·endTransaction结束事务
·insert(String table ,String nullColumnHack ,ContentValues values)向表格table中插入数据。数据来自于values。成功插入后返回新插入行的ID值,返回-1表示插入失败。ContentValues类似于map,存放键值对。提供了put(String key, Xxx values)key为数据列的列名,这个方法用于存入数据、getAsXxx(String key)方法用于取出数据
·public int update(String table,ContentValues values,String whereClause,String[] whereArgs)更新数据库。Table为表名;values为ContentValues对象,包含更新到表中的行数据;whereClause,where条件语句,用于精确指定要更新的行,不包含Where关键字。当值为null时,表示更新所有数据;whereArgs,where条件语句中表达式占位符?的参数值列表,只支持String类型。
·public int delete(String table,String whereClause,String[] whereArgs)。如果后两参数为null,则表示删除表名为table的表中的所有内容,不会删除这张表
·public Cursor rawQuery(String sql ,String[] selectionArgs)执行查询语句sql,返回的结果保存在Cursor实例中。程序中可以使用这个Cursor实例来实例化一个SimpleCursorAdapter,再将这个SimpleCursorAdapter作为参数传给listView的setAdapter,将结果显示出来。其中sql是要执行的查询语句,selectionArgs是参数列表,对应于sql中的占位符。关于Cursor的使用在Demo里面有介绍
·public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)完成查询操作,是将sql语句分开了,作为query的参数传递进来。返回值也是Cursor实例对象
SQLiteOpenHelper类
是一个抽象类,主要作用是完成数据库的创建和数据库版本的管理。在创建数据库时这个类用的比较多。使用时需要创建一个extends SQLiteOpenHelper,并实现onCreate、onUpdate抽象方法的子类来完成对数据库的各种操作。数据库文件默认在:/data/data/<程序包名>/databases/这个目录下。数据库名称一般后缀为.db3
·onCreate(SQLiteDatabase db)创建SQLiteOpenHelper子类的实例时,在其构造方法中会调用SQLiteOpenHelper的构造方法,这个方法会创建一个SQLite数据库。如果这个数据库是第一次创建,那么就会执行这个onCreate方法。方法传入的参数是构造方法创建的数据库的实例化。一般在这个方法中使用传入的db,调用它的方法进行表格的创建等。
·onUpdate(SQLiteDatabase db,int oldVersion,int new Version) 当需要对已经存在的数据库结构进行更新时,如修改表字段的名字、新增加表、字段,删除已有的表等,就可以使用这个方法。这个方法不需要显式的调用。当创建SQLiteOpenHelper子类的实例时,如果传入的版本参数与之前的版本不同就会被调用
·close关闭已打开的数据库。一般在onDestroy方法中被调用
·getReadableDatabas()创建或打开数据库
·getWriteableDatabase()以可读写方式创建或打开数据库,返回可读写数据库的SQLiteDatabase对象。如果数据库不能以写方式打开,则抛出SQLiteException异常。
getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
注意:getWritableDatabase(),getReadableDatabase的区别是当数据库写满时,调用前者会报错,调用后者不会,所以如果不是更新数据库的话,最好调用后者来获得数据库连接。
·
数据库操作程序过程。
首先继承SQLiteOpenHelper,添加构造方法。这个方法中调用父类的构造方法,主要功能是完成数据库的创建。实现其两个虚函数,在这两个虚函数中可以添加一些其他的操作。然后创建这个子类的实例,完成数据库的创建。再调用这个实例的getReadableDatabase()或者getWriteableDatabase方法,返回SQLiteDatabase对象。这样就可以利用这个对象中提供的各种方法来操作数据库了。
创建表格操作
·String sql = “CREATE TABLE TAB_USER ( _id INTEGER PRIMARY KEY, name TEXT NOT NULL)”;
·db.execSQL (sql);
添加向表格中一列
·String upgradesql = “ALTER TABLE TBL_USER ADD COLUMN created_dt timestamp NOT NULL DEFAULT ‘2010-10-01 COLLATE NOCASE;’”;
·db.execSQL(upgradesql);
插入数据
·ContentValues values = new ContentValues();
·values.put(“name” , “孙悟空”);
·values.put(“age” , 500);
·long rowid = db.insert(“person_inf” , null , values);其中第二个参数可以为”_id”
删除表格
·db.delete(TBL_USER , “_id = ?” ,new String[] {5});删除_id = 5的一行
或
·db.beginTransaction();
·String sql = "DROP TABLE "+tablename;
·sqlDb.execSQL(sql); // 执行SQL语句
·sqlDb.setTransactionSuccessful();// 设置事务成功标志
·
常用的SQL语句
1. create table 创建一个数据库表格
2. drop table 从数据库中删除一个表格 DROP TABLE tablename;
3.SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;
4
Demo1
下面是实现SQLiteOpenHelper抽象类。实现两个抽象方法onCreate和onUpdate。可以写一个构造方法,调用父类的构造方法,传入参数,来创建一个SQLiteDatabase实例。onCreate方法和onUpdate不需要程序显式调用,是系统自动调用的。这两个方法中都可以使用系统传进来的SQLiteDatabase实例对象来进行表格的添加或更新等操作。
public class MyDbHelper extends SQLiteOpenHelper {
// 声明数据库名字符串常量
private static final String DB_NAME = "WiFiInfo.db3";
/**
* 定义构造方法,用于创建数据库
* @param context
* @param version
*/
public MyDbHelper(Context context, int version) {
super(context, DB_NAME, null, version);
}
/**
* 第一次创建数据库后调用,可在此方法中完成数据库表的创建
*/
@Override
public void onCreate(SQLiteDatabase db) {
}
/**
* 完成数据库结构的更新操作
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Demo2
这是一个实现获得数据库中所有表格的方法,返回的结果保存在Cursor中。
public Cursor showAllTable(){ //显示创建的表格
Cursor c = null;
//StringBuffer str = new StringBuffer();
try{
// 启用事务
sqlDb.beginTransaction();
String sql = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
// 执行SQL语句
c = sqlDb.rawQuery(sql, null);
// 设置事务成功标志
sqlDb.setTransactionSuccessful();
}catch(Exception ex){
ex.printStackTrace();
}finally{
// 结束事务
sqlDb.endTransaction();
}
return c;
Demo3
这个方法是使用query获得表名为tbName中所有的数据。相当于select * from tbName
public Cursor getContacts(String tbName){
//查询tbl表所有数据,并按照_id升序排列
Cursor c =sqlDb.query(tbName, null, null, null, null, null, "_id");
return c;
}
Demo4
游标Cursor是几乎所有的数据库都会使用。它位于结果集之上,可以对结果集进行前、后或随机的读取。在Android中,Cursor自身是一个标准的Java接口,定义了对结果集进行操作的各种方法。Android系统提供了默认的Cursor实现类,如果想再查询结果返回前进行控制,可以自定义继承自CursorFactory的类来对结果集进行操作。Cursor的值指向结果集中的第一个,如果取结果,首先要moveToNext。如果第一次调用moveToNext返回false也代表没有数据。
·moveToFirst移动游标到查询结果集第一行位置
·moveToLast移动游标到查询结果集最后一行位置
·moveToNext移动游标到结果集下一行
·moveToPosition移动游标到查询结果集指定位置
·getString(int columnIndex)获取columnIndex所指定列数据,并将其转换为String。如getString(0)返回结果中第0列的元素的String值。
·getInt(int columnIndex)获得columnIndex指定列的数据,返回32位int型数据
其他方法可以查看android SDK
下面的程序是将c中第0列的数据取出来,如果不是“android_metadata”存放在String[]类型的数组中。
while(c.moveToNext()){
if(!c.getString(0).equals("android_metadata"))
{
ad[i]=c.getString(0);
i++;
}
}