Android - kotlin 資料庫的使用——技術積累
前言:
專案中使用到資料庫進行一些邏輯操作,有使用過,但是一段時間不看,已經淡忘。現在總結下對資料庫的基本操作,幫助自己回憶。
首先:
我們先複習下對Android對資料庫的基本操作,關心kotlin操作資料庫的同學可以直接往下翻:
- SQLiteDatabase 的使用,增刪改查。
- 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裡面的簡單操作資料庫的方法