Android-Kotlin-數據持久化技術點

1.數據持久化的方式

Android中主要提供了三種數據持久化的方式:文件存儲、SharePreferences存儲以及數據庫存儲

2.文件存儲

fun save(inputText:String){
    val output=openFileOutput("data", Context.MODE_PRIVATE)
    val write=BufferedWriter(OutputStreamWriter(output))
    write.use { 
        it.write(inputText)
    }
}

借助于Context的openFileOutput方法

第一個參數是文件名,這個參數不能帶路徑,因為所有的文件默認保存到/data/data/<packagename>/files/目錄下

第二個參數是文件的操作模式,MODE_PRIVATE:表示文件名相同內容會直接覆蓋 MODE_APPEND:表示文件存在則直接追加

這里使用了一個use的擴展函數,這個函數中的代碼全部執(zhí)行完之后會自動將外層的流關閉,不需要再手動寫finally進行流關閉了

另外Kotlin中沒有try catch,不需要像java那些寫try catch代碼了

3.文件中讀取數據

fun read():String{
    val content=StringBuilder()
    val input=openFileInput("data")
    val reader=BufferedReader(InputStreamReader(input))
    reader.use {
        reader.forEachLine { 
            content.append(it)
        }
    }
    return content.toString()
}

借助openFileInput方法

forEachLine是Kotlin的一個內置函數,它會將讀到的每一行內容都回到Lambda表達式中,然后完成拼接

4.將數據保存到SharedPreferences

fun saveToSharePreference(content:String){
    getSharedPreferences("data",Context.MODE_PRIVATE).edit().apply {
        putString("name","jack")
        putInt("age",16)
        putString("desc",content)
        apply()
    }
    
}

SharePreference保存數據是以鍵值對的方式保存的

保存的路徑是/data/data/<packagename>/shared_prefs/目錄下

5.從SharedPreferences讀取數據

fun readFromSharePreference() {
    getSharedPreferences("data", Context.MODE_PRIVATE).apply {
        val name = getString("name", "")
        val age = getInt("age", 0)
        val desc = getString("desc", "")
        Log.d(TAG, "name=$name,age=$age,desc=$desc")
    }
}

6.SQLite數據庫存儲

想使用數據庫google提供了SQLiteOpenHelper來完成這些操作

class MySqliteDataHelper(val context: Context,name:String,version:Int):SQLiteOpenHelper(context,name,null,version) {

    private val createBook="create table Book( " +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)"


    private val createCategory="create table Category( id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)"

    override fun onCreate(db: SQLiteDatabase?) {
        db?.execSQL(createBook)
        db?.execSQL(createCategory)
        showToast("create books success")
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //根據版本號判斷
        if (oldVersion<=1){
            db?.execSQL(createCategory)
        }

        if (oldVersion<=2){
            db?.execSQL("alter table Book add column category_id")
        }

        //...

    }
}

這個是抽象類,需要一個寫一個實現(xiàn)類,這個抽象類構造方法有四個參數

第一個是Context上下文

第二個是數據庫名字

第三個是允許查詢數據庫返回一個自定義的cursor

第四個是當前數據庫的版本號

onCreate方法只會調用一次,當數據庫存在之后,onCreate方法便不會執(zhí)行了,所以如果需要有調整比如添加一個新表或者添加一個字段等需要在onUpgrade方法中執(zhí)行

數據庫創(chuàng)建之后,存在的路徑是/data/data/<packagename>/目錄下

初始化SQLiteOpenHelper之后,可以調用getReadableDatabase或者getWriteableDatabase

getReadableDatabase:這個是以只讀的方式打開數據庫

getWriteableDatabase:這個是可讀可寫的方式打開數據庫(如果磁盤滿了,會出現(xiàn)異常)

查看數據庫中的表是否創(chuàng)建成功,可以借助Android studio插件 Database Navigator,安裝插件之后,Android studio 左側會出現(xiàn)DB Browser工具,將數據庫從sd卡導出來直接導入到這個工具就可以查看了。

7.對數據庫進行增刪查改

fun insertData(view: View){
    val value=ContentValues().apply {
        put("name","斗破蒼穹")
        put("author","tom")
        put("pages",454)
        put("price",16.68)
    }
    writableDatabase.insert("Book",null,value)
}

給Book表插入一條數據,insert方法,第一個參數是表名字,第二個參數是用戶未指定添加的時候給某些可為空的列自動賦值NULL,第三個參數是ContentValues對象。

fun updateData(view: View){
    writableDatabase = mySqliteDataHelper.writableDatabase
    val value=ContentValues()
    value.put("price",12.68)
    writableDatabase.update("Book",value,"name=?", arrayOf("斗破蒼穹"))
}

更新數據,第二個參數是更新的內容,第三個參數是where占位符,第四個參數是占位符的值

fun deleteData(view: View){
    writableDatabase=mySqliteDataHelper.writableDatabase
    writableDatabase.delete("Book","price>?", arrayOf("12.68"))
}

刪除數據,第二個參數是where占位符,第三個參數是占位符的值

fun queryData(view: View){
    writableDatabase=mySqliteDataHelper.writableDatabase
    val cursor = writableDatabase.query(
        "Book", null, null,
        null, null, null, null
    )
    while (cursor.moveToNext()){
        val name = cursor.getString(cursor.getColumnIndex("name"))
        val page = cursor.getInt(cursor.getColumnIndex("pages"))
    }
}

查詢數據,并對結果進行遍歷,query方法參數有些多,不過好多時候不需要全部寫

//參數介紹

第一個參數:表名

第二個參數:查詢的列名字

第三個參數:指定where的約束條件

第四個參數:為where指定的展位符設置的值

第五個參數:指定需要group by

第六個參數:對group by的結果進行一步約束

第七個參數:指定查詢結果的排序

8.數據庫事務操作

//使用事務
fun useTransaction(){
    writableDatabase=mySqliteDataHelper.writableDatabase
    writableDatabase.beginTransaction()
    writableDatabase.delete("Book",null,null)

    val values = ContentValues().apply {
        put("name","斗羅大陸")
        put("author","tom")
        put("pages",454)
        put("price",15.68)
    }

    writableDatabase.insert("Book",null,values)
    writableDatabase.setTransactionSuccessful()
    writableDatabase.endTransaction()
}

數據庫的事務中的內容,必須全部完成才可以,否則已經執(zhí)行的語句會直接回滾,保留原來的舊數據,銀行轉賬等都需要用到事務操作。

9.數據庫升級

  override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //根據版本號判斷
    if (oldVersion<=1){
         db?.execSQL(createCategory)
     }
    if (oldVersion<=2){
        db?.execSQL("alter table Book add column category_id")
    }

    //...

}

數據庫升級,最好是根據oldVersion進行判斷,這樣如果從2升到3,只會執(zhí)行后邊的if語句,如果是從1升級到3則會執(zhí)行兩個語句,這樣不管版本如何進行升級都可以保證數據庫的表結構是最新的,而且表中的數據也不會丟失。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容