SQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机、PDA等)适量数据存取。SQLite只是一个文件。
1、简介SQLiteDatabase
Android提供了SQLiteDatabase代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的SQLiteDatabase对象,接下来就可通过SQLiteDatabase对象来管理、操作数据库了。
SQLiteDatabase提供了如下静态方法打开一个文件对应的数据库:
a、static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags):打开path文件代表的SQLite数据库。
b、static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabaseCursorFactory factory):打开或创建(如果不存在)file文件所代表的SQLite数据库。
c、static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabaseCursorFactory factory):打开或创建(如果不存在)path文件所代表的SQLite数据库。
在程序中获取SQLiteDatabase对象之后,接下来就可调用SQLiteDatabase的如下方法来操作数据库:
a、execSQL(String sql,Object[ ] bindArgs):执行带占位符的SQL语句。
b、execSQL(String sql):执行SQL语句。
c、insert(String table,String nullColumnHack,ContentValues values):向执行表中插入数据。
d、update(String table ,ContentValues values,String whereClause,String[ ] whereArgs):更新特定表中的特定数据
e、delete(String table,String whereClause,String[ ] whereArgs):删除指定表中的特定数据。
f、Cursor query(String table,String[ ] columns,String selection,String[ ] selectionArgs,String groupBy,String having,String orderBy):对执行数据表执行查询。
g、Cursor query(String table,String[ ] columns,String selection,String[ ] selectionArgs,String groupBy,String having,String orderBy,String limit):对执行数据表执行查询。limit参数控制最多查询几条记录(用于控制分页的参数)。
h、Cursor query(boolean distinct,String table,String[ ] columns,String selection,String[ ] selectionArgs,String groupBy,String having,String orderBy,String limit):对指定表执行查询语句。其中第一个参数控制是否取出重复值。
i、rawQuery(String sql,String[ ] selectionArgs):执行带占位符的SQL查询。
j、beginTransaction():开始事物。
k、endTransaction():结束事物。
上面查询方法都是返回一个Cursor对象,Cursor提供了如下方法来移动查询结果的记录指针:
a、move(int offset):将记录指针向上或向下移动指定的行数,offset为整数时向下移,为负数时向上移。
b、boolean moveToFirst():将记录指针移动到第一行,如果移动成功则返回true。
c、boolean moveToLast():将记录指针移动到最后一行,如果移动成功则返回true。
d、boolean moveToNext():将记录指针移动到下一行,如果移动成功则返回true。
e、boolean moveToPosition(int position):将记录指针移动到指定的行,如果移动成功则返回true。
f、boolean moveToPrevious():将记录指针移动到上一行,如果移动成功则返回true。
一旦将记录指针移动到指定行之后,接下来就可以调用Cursor的getXxx()方法获取改行指定列的数据。
2、创建数据库和类
使用SQLiteDatabase的静态方法可以打开或创建数据库,示例代码如下:
SQLiteDatabase.openOrCreateDatabase(“/mnt/db/temp.db3”,null);
//如果/mnt/db/目录下的temp.db3文件(该文件就是一个数据库)存在,那么程序就是打开数据库,如果该文件不存在,则代码将会在该目录下创建temp.db3文件(即对应于数据库)。第二个参数SQLIteDatabase.CursorFactory是一个用于返回Cursor的工厂,如果参数设为null,意味着使用默认的工厂。
上面的代码返回一个SQLiteDatabase对象,该对象的execSQL可执行任意的SQL语句,因此可通过如下代码创建数据表:
sql=“create table user_inf(user_id integer primary key,user_name varchar(255),user_pass varchar(255))”;
db.execSQL(sql);
3、使用SQL语句操作SQLite数据库
SQLiteDatabase的execSQL方法可执行任意SQL语句,包括带占位符的SQL语句。但由于该方法没有返回值,一般用于执行DDL语句或DML语句:如果需要执行查询语句,可以调用SQLiteDatabase的rawQuery(String sql,String[ ] selectionArgs)方法。示例代码如下:
db.execSQL(“insert into news_inf values(null,?,?)“,new String[ ] {title,content}) //执行插入语句
使用SQLiteDatabase进行数据库操作的步骤如下:
a、获取SQLiteDatabase对象,它代表了与数据库的连接。
b、调用SQLiteDatabase的方法来执行SQL语句。
c、操作SQL语句的执行结果,比如用SimpleCursorAdapter封装Cursor。
d、关闭SQLiteDatabase,回收资源。
SQLite有一个特点:它允许把各种类型的数据保存到任何类型字段中,开发者可以不用关心声明该字段所使用的数据类型。例如可以把字符串类型的值存入INTEGER类型字段中,也可以把数值类型的值存入布尔型的字段中。
但有一个特殊情况:定义为INTEGER PRIMARY KEY的字段只能存储64位整数,当向这种字段保存除整数意外的其它类型的数据时,SQLite会产生错误。
由于SQLite允许存入数据时忽略底层数据列实际的数据类型,因此在编写建表语句时可省略数据列后面的类型声明,示例如下:
create table my_test ( _id primary key autoincrement,name,pass,gender);
4、使用特定方法操作SQLite数据库
(1)使用insert方法插入记录
SQLiteDatabase的insert方法签名为long insert(String table,String nullColumnHack,ContentValues values),参数说明如下:
table:代表想插入数据的表名
nullColumnHack:代表强行插入null值的数据列的列名。
values:代表一行记录的数据。
insert方法插入的一行记录使用ContentValues存放,ContextValues类似于Map,它提供了put(String key,Xxx value)(其中key为数据列的列名)方法用于存入数据,getAsXxx(String key)用于取出数据。
示例代码如下:
ContextValues values=new ContextValues();
values.put(”name“,”孙悟空“);
values.put(”age“,500);
long rowid=db.insert(”person_inf“,null,values);
不管第三个参数是否包含数据,执行insert()方法总会添加一条记录,如果第三个参数为空,会添加一条除主键之外其它字段值都为null的记录。
一般来说,第二个参数指定的列名不应该是主键列的列名,也不应该是非空列的列名,否则强行往这些数据列插入null会引发异常。
其对应的SQL语句如下:
insert into<表名>(key1,key2......) values(value1,value2.......)
(2)使用update方法更新记录
SQLiteDatabase的update方法签名为update(String table ,ContentValues values,String whereClause,String[ ] whereArgs),参数说明如下:
table:代表想更新数据的表名。
values:代表想更新的数据。
whereClause:满足该whereClause子句的记录将会被更新。
whereArgs:用于为whereClause子句传入参数。
该方法返回受此uodate语句影响的记录的条数。
例如我们想更新person_inf表中所有主键大于20的人的人名,代码如下:
ContextValues values=new ContextValues();
values.put(”name“,”新人名“);
int result=db.update(”person_inf“,values,”_id>?“,,”new Integer[ ]{20}“);
对应的SQL语句如下:
update <table> set key1=value1,key2=value2..... where <whereClause>
(3)使用delete方法删除记录
SQLiteDatabase的delete方法签名为:delete(String table,String whereClause,String[ ] whereArgs),参数说明如下:
table:代表想删除数据的表名。
whereClause:满足该whereClause子句的记录将会被删除。
whereArgs:用于为whereClause子句传入参数
该方法返回受此delete语句影响的记录的条数。
例如我们想删除person_inf表中所有人名以孙开头的记录,代码如下:
int result=db.delete(”person_inf“,”person_name like ?“,new String[ ] {"孙_"});
对应的SQL语句如下:
delete <table> where <whereClause>
(4)使用query方法查询记录
SQLiteDatabase的query方法的签名为Cursor query(boolean distinct,String table,String[ ] columns,String selection,String[ ] selectionArgs,String groupBy,String having,String orderBy,String limit),参数说明如下:
distinct:指定是否去除重复记录。
table:执行查询数据的表名。
columns:要查询出来的列名,相当于select语句select关键字后面的部分。
selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句中允许使用占位符”?“。
selectionArgs:用于为selection子句中占位符传入参数值,值在数组中的位置与占位符在语句中的位置必须一致,否则会出现异常。
groupBy:用于控制分组。相当于select语句group by关键字后面的部分。
having:用于对分组进行过滤。相当于select语句having关键字后面的部分。
orderBy:用于对记录进行排序。相当于select语句order by关键字后面的部分,如personid desc,age asc
limit:用于进行分页,相当于select语句limit关键字后面的部分,例如5,10
当应用程序需要进行”条件不确定“的查询(即查询条件需要动态改变的查询)时,使用这个query方法可以避免手动拼接SQL语句。
例如想查询出person_inf表中人名以”孙“开头的记录,代码如下:
Cursor cursor=db.query(”person_inf“,new String[ ] {”_id,name,age“},”name like?“,new String[ ]{"孙%"},null,null,”personid desc“,”5,10“);
cursor.close();
5、事务
SQLiteDatabase中包含如下两个方法来控制事务:
beginTransaction():开始事务。
endTransaction():结束事务。
除此之外,SQLiteDatabase还提供了如下方法判断当前上下文是否处于事务环境中。
inTransaction():如果当前上下文处于事务中,返回true,否则返回false;
当程序执行endTransaction()方法时将会结束事务--到底是提交事务,还是回滚事务?取决于SQLiteDatabase是否调用了setTransactionSuccessful()方法来设置事务标志,如果程序事务执行中调用该方法设置了事务成功则提交事务,否则程序将回滚事务。示例代码:
db.beginTransaction();//开始事务
try{
//执行DML语句
......
db.setTransactionSuccessful();//调用该方法设置事务成功。否则endTransaction()方法将回滚事务
}
finally{
db.endTransaction();//由事务的标志决定是提交事务还是回滚事务
}
6、SQLiteOpenHelper类
SQLiteOpenHelper是Android提供的一个管理数据库的工具类,可用于管理数据库的创建和版本更新。一般的用法是创建SQLiteOpenHelper的子类,并扩展它的onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)方法。
SQLiteOpenHelper包含如下常用的方法:
一旦得到了SQLiteOpenHelper对象之后,程序无需使用SQLiteDatabase的静态方法创建SQLiteDatabase实例,而且可以用getWritableDatabase()或getReadableDatabase()方法来获取一个用于操作数据库的SQLiteDatabase实例。a、synchronized SQLiteDatabase getReadableDatabase():以读写的方式打开数据库对应的SQLiteDatabase对象。
b、synchronized SQLiteDatabase getWritableDatabase():以写的方式打开数据库对应的SQLiteDatabase对象。
c、abstract void onCreate(SQLiteDatabase db):当第一次创建数据库时回调该方法。
d、abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion):当数据库版本更新时回调该方法。
e、synchronized void close():关闭所有打开的SQLiteDatabase。