前言:
项目中使用到数据库进行一些逻辑操作,有使用过,但是一段时间不看,已经淡忘。现在总结下对数据库的基本操作,帮助自己回忆。
首先:
我们先复习下对Android对数据库的基本操作,关心kotlin操作数据库的同学可以直接往下翻:
**
**
SQLiteDatabase是创建和使用SQLite数据库的API。
操作数据库的两种方式;
一种是单纯的执行sql 语句进行增删改查,需要我们拼接sql语句比较麻烦。
一种是利用android 提供的增删改查的函数去操作数据库。
SQLiteDatabase的常用方法 :
方法名称 | 方法表示含义 |
---|---|
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory) | 打开或创建数据库 |
insert(String table,String nullColumnHack,ContentValues values) | 插入一条记录 |
delete(String table,String whereClause,String[] whereArgs) | 删除一条记录 |
query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy) | 查询一条记录 |
update(String table,ContentValues values,String whereClause,String[] whereArgs) | 修改记录 |
execSQL(String sql) | 执行一条SQL语句 |
close() | 关闭数据库 |
1、打开或者创建数据库
openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)打开或者创建一个数据库。它会自动去检测是否存在这个数据库,如果存在则打开,不存在则创建一个数据库;创建成功则返回一个SQLiteDatabase对象,否则抛出异常FileNotFoundException。
下面是创建名为“xx.db”数据库的代码:
path 数据库创建的路径
factory 一般设置为null就可以了
openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)
db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/xx.db",null);
2、创建表
//下面的代码创建了一张用户表,属性列为:id(主键并且自动增加)、sname(学生姓名)、snumber(学号)
private void createTable(SQLiteDatabase db){
//创建表SQL语句
String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)";
//执行SQL语句
db.execSQL(stu_table);
}
3、插入数据
SQLiteDatabase的insert(String table,String nullColumnHack,ContentValues values)方法,
参数1 表名称,
参数2 空列的默认值
参数3 ContentValues类型的一个封装了列名称和列值的Map;
编写SQL执行语句插入数据库;
private void insert(SQLiteDatabase db){
//插入数据SQL语句
String stu_sql="insert into stu_table(sname,snumber) values('xiaoming','01005')";
//执行SQL语句
db.execSQL(sql);
}
4、删除数据
调用SQLiteDatabase的delete(String table,String whereClause,String[] whereArgs)方法
参数1 表名称
参数2 删除条件
参数3 删除条件值数组
编写SQL执行语句删除数据;
private void delete(SQLiteDatabase db) {
//删除SQL语句
String sql = "delete from stu_table where _id = 6";
//执行SQL语句
db.execSQL(sql);
}
5、修改数据
调用SQLiteDatabase的update(String table,ContentValues values,String whereClause, String[] whereArgs)方法
参数1 表名称
参数2 跟行列ContentValues类型的键值对Key-Value
参数3 更新条件(where字句)
参数4 更新条件数组
编写SQL执行语句修改数据;
private void update(SQLiteDatabase db){
//修改SQL语句
String sql = "update xx_table set snumber = 654321 where id = 1";
//执行SQL
db.execSQL(sql);
}
6、查询数据
在Android中查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法,具体方法如下:
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
各个参数的意义说明:
参数table:表名称
参数columns:列名称数组
参数selection:条件字句,相当于where
参数selectionArgs:条件字句,参数数组
参数groupBy:分组列
参数having:分组条件
参数orderBy:排序列
参数limit:分页查询限制
参数Cursor:返回值,相当于结果集ResultSet
Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法getString()等.
Cursor游标常用方法
方法名称 | 方法描述 |
---|---|
getCount() | 获得总的数据项数 |
isFirst() | 判断是否第一条记录 |
isLast() | 判断是否最后一条记录 |
moveToFirst() | 移动到第一条记录 |
moveToLast() | 移动到最后一条记录 |
move(int offset) | 移动到指定记录 |
moveToNext() | 移动到下一条记录 |
moveToPrevious() | 移动到上一条记录 |
getColumnIndexOrThrow(String columnName) | 根据列名称获得列索引 |
getInt(int columnIndex) | 获得指定列索引的int类型值 |
getString(int columnIndex) | 获得指定列缩影的String类型值 |
private void query(SQLiteDatabase db) {
//查询获得游标
Cursor cursor = db.query ("usertable",null,null,null,null,null,null);
//判断游标是否为空
if(cursor.moveToFirst() {
//遍历游标
for(int i=0;i
7、删除指定表
private void drop(SQLiteDatabase db){
//删除表的SQL语句
String sql ="DROP TABLE stu_table";
//执行SQL
db.execSQL(sql);
}
**
**
该类是SQLiteDatabase一个辅助类。这个类主要生成一 个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase()或者 getReadableDatabase()方法的时候,如果当时没有数据,那么Android系统就会自动生成一个数据库。 SQLiteOpenHelper 是一个抽象类,我们通常需要继承它,并且实现里面的3个函数:
1.onCreate(SQLiteDatabase)
在数据库第一次生成的时候会调用这个方法,也就是说,只有在创建数据库的时候才会调用,当然也有一些其它的情况,一般我们在这个方法里边生成数据库表。
2. onUpgrade(SQLiteDatabase,int,int)
当数据库需要升级的时候,Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表,并建立新的数据表,当然是否还需要做其他的操作,完全取决于应用的需求。
3. onOpen(SQLiteDatabase):
这是当打开数据库时的回调函数,一般在程序中不是很常使用。
**
**
Anko提供了很多强大的SQLiteOpenHelper来可以大量简化代码,首先需要依赖anko的sqlite模块:
在使用之前,先在gradle中添加引用
compile "org.jetbrains.anko:anko-sqlite:$anko_version"
**
**
ManagedSQLiteOpenHelper是一个抽象类,所以使用的时候也需要我们创建一个帮助类集成ManagedSQLiteOpenHelper,然后进行我们的业务操作。
class DatabaseOpenHelper : ManagedSQLiteOpenHelper
使用ManagedSQLiteOpenHelper只需要
dbHelper.use{
//1、插入记录
//insert(...)
//2、更新记录
//update(...)
//3、删除记录
//delete(...)
//4、查询记录
//query(...)或者rawQuery(...)
use 的源码:
public fun use(f: SQLiteDatabase.() -> T): T {
try {
return openDatabase().f()
} finally {
closeDatabase()
}
}
分析:首先use接收一个SQLiteDatavase的扩展函数,所以可以使用this在大括号中并处于SQLiteDatavase对象中。这个扩展函数可以返回一个值。
由于使用try-finally,所以一定会去关闭数据库。
其中表的查询操作还要借助于SQLite已有的游标类Cursor来实现,上述代码中的query和rawQuery方法,返回的都是Cursor对象,那么获取查询结果就得根据游标的指示一条一条遍历结果集合。下面是Cursor类的常用方法:
游标控制类方法,用于指定游标的状态:
方法 | 作用 |
---|---|
close | 关闭游标 |
isClosed | 判断游标是否关闭 |
isFirst | 判断游标是否在开头 |
isLast | 判断游标是否在末尾 |
游标移动类方法,把游标移动到指定位置:
方法 | 作用 |
---|---|
moveToFirst | 移动游标到开头 |
moveToLast | 移动游标到末尾 |
moveToNext | 移动游标到下一个 |
moveToPrevious | 移动游标到上一个 |
move | 往后移动游标若干偏移量 |
moveToPosition | 移动游标到指定位置 |
3、获取记录类方法,可获取记录的数量、类型以及取值。
方法 | 作用 |
---|---|
getCount | 获取记录数 |
getInt | 获取指定字段的整型值 |
getFloat | 获取指定字段的浮点数值 |
getString | 获取指定字段的字符串值 |
getType | 获取指定字段的字段类型 |
2、创建表
我们可以用object来提前定义表,如:
object PersionTable{
val TABLE = "Persion"
val ID = "_id"
val NAME = "name"
}
使用createTable来创建表
fun SQLiteDatabase.createTable(tableName: String, ifNotExists: Boolean = false, vararg columns: Pair)
第一个参数是表名
第二个参数为true时,创建前会检查表是否存在
后面的参数是Pair类型的vararg,是表的列名和类型。(vararg在java中也有,是一种在函数中传入很多相同类型的参数)
db.createTable(PersionTable.TABLE, true,
Pair(PersionTable.ID, INTEGER + PRIMARY_KEY),
Pair(PersionTable.NAME, TEXT))
3、SqlType和SqlTypeModifier
Anko中有一个特殊类型SqlType,可以和SqlTypeModifier混合,如上面的PRIMARY_KEY。SqlType中“+”操作符被重写了,如下:
fun SqlType.plus(m: SqlTypeModifier) : SqlType {
return SqlTypeImpl(name, if (modifier == null) m.toString()
else "$modifier $m")
}
会返回新的SqlType,这样使用“+”操作符可以将多个装饰符组合起来。
4、to函数
kotlin标准库中含有一个to函数,如下:
public fun A.to(that: B): Pair = Pair(this, that)
使用to函数, 创建表的代码可以这样写
db.createTable(PersionTable.TABLE, true,
PersionTable.ID to INTEGER + PRIMARY_KEY,
PersionTable.NAME to TEXT)
5、parseList函数和RowParser、MapRowParser接口
RowParser、MapRowParser是接口,我们需要去实现它们。
parseList函数使用RowParser和MapParser将cursor转换为对象集合。不同的是,RowParser是依赖列的顺序,得到的是一个array;而MapRowParser是将column名作为key值,得到一个map。
6、parseOpt和parseSingle
这两个都是在结果中返回单一对象,不同的是parseOpt可以返回null;而parseSingle则只能返回非null对象,当找不到这条数据会抛出一个错误。
站在巨人的肩膀上,感谢
手把手教你用ManagedSQLiteOpenHelper实现数据库
Android DatabaseOpenHelper 自定义打开创建数据库帮助类
ManagedSQLiteOpenHelper
SQLiteDatabase里面的简单操作数据库的方法