前言:
項目中使用到數據庫進行一些邏輯操作,有使用過,但是一段時間不看,已經淡忘。現在總結下對數據庫的基本操作,幫助自己回憶。
首先:
我們先複習下對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裏面的簡單操作數據庫的方法