Android - kotlin 数据库的使用——技术积累

前言:
项目中使用到数据库进行一些逻辑操作,有使用过,但是一段时间不看,已经淡忘。现在总结下对数据库的基本操作,帮助自己回忆。

首先:

我们先复习下对Android对数据库的基本操作,关心kotlin操作数据库的同学可以直接往下翻:

  1. SQLiteDatabase 的使用,增删改查。
  2. SQLiteOpenHelper SQLiteDatabase辅助类的使用。

**

《一, SQLiteDatabase 的使用,增删改查》

**

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<cursor.getCount();i++){  
cursor.move(i);  
//获得ID  
int id = cursor.getInt(0);  
//获得用户名  
String username=cursor.getString(1);  
//获得密码  
String password=cursor.getString(2);  
//输出用户信息 System.out.println(id+":"+sname+":"+snumber);  
}  
}  
}

7、删除指定表

private void drop(SQLiteDatabase db){  
//删除表的SQL语句  
String sql ="DROP TABLE stu_table";  
//执行SQL  
db.execSQL(sql);  
}  

**

《二,SQLiteOpenHelper 辅助类的使用》

**

该类是SQLiteDatabase一个辅助类。这个类主要生成一 个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase()或者 getReadableDatabase()方法的时候,如果当时没有数据,那么Android系统就会自动生成一个数据库。 SQLiteOpenHelper 是一个抽象类,我们通常需要继承它,并且实现里面的3个函数:

1.onCreate(SQLiteDatabase)

在数据库第一次生成的时候会调用这个方法,也就是说,只有在创建数据库的时候才会调用,当然也有一些其它的情况,一般我们在这个方法里边生成数据库表。

2.  onUpgrade(SQLiteDatabase,int,int) 

当数据库需要升级的时候,Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表,并建立新的数据表,当然是否还需要做其他的操作,完全取决于应用的需求。

3.  onOpen(SQLiteDatabase):

这是当打开数据库时的回调函数,一般在程序中不是很常使用。

**

Kotlin中使用数据库

**

Anko提供了很多强大的SQLiteOpenHelper来可以大量简化代码,首先需要依赖anko的sqlite模块:

在使用之前,先在gradle中添加引用

compile "org.jetbrains.anko:anko-sqlite:$anko_version"

**

1、ManagedSQLiteOpenHelper

**

ManagedSQLiteOpenHelper是一个抽象类,所以使用的时候也需要我们创建一个帮助类集成ManagedSQLiteOpenHelper,然后进行我们的业务操作。

class DatabaseOpenHelper : ManagedSQLiteOpenHelper

使用ManagedSQLiteOpenHelper只需要

dbHelper.use{  
    //1、插入记录
    //insert(...)
    //2、更新记录
    //update(...)
    //3、删除记录
    //delete(...)
    //4、查询记录
    //query(...)或者rawQuery(...)

use 的源码:

public fun <T> 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<String, SqlType>)  
第一个参数是表名
第二个参数为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, B> A.to(that: B): Pair<A, B> = 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里面的简单操作数据库的方法

猜你喜欢

转载自blog.csdn.net/qq_30974087/article/details/83379380