1. 程式人生 > >Android - kotlin 資料庫的使用——技術積累

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裡面的簡單操作資料庫的方法