日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android持久化存储(3)SQLite数据库的使用

發布時間:2024/9/21 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android持久化存储(3)SQLite数据库的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.什么是SQlite

SQLite是由C語言編寫的一款輕型數據庫,因占用資源小,處理速度快,功能齊全,特別適用于移動設備,最重要的是開源,任何人都可以使用它,許多開源項目(PHP,Python)和當今兩大手機操作系統Android和iOS都使用了SQLite,造就了SQLite成為目前世界上最常見的數據庫引擎。

2.SQLite特點

除了占用資源小,處理速度快等優點,SQLite還有自己的特點,那就是支持弱數據類型,其他主流SQL數據庫通常支持強類型的數據,也就是每一列的類型都必須預先指定,如果輸入的數據和指定數據類型對不上則報錯,而SQLite采用的是弱類型,也就是說,創建一個表時指定某列的數據類型,但是你可以把任何數據類型插入該列,SQLite將檢查它的類型,如果該類型與關聯的列不匹配,則SQLite會嘗試將該值轉換成該列的類型,如果不能轉換,則該值將作為其本身具有的類型存儲。

SQLite支持數據類型如下:包括NULL、INTEGER、REAL、TEXT和BLOB

  • NULL: 該值是空值;
  • INTEGER: 該值是一個有符號整數,根據值的大小以1、2、3、4、6或8個字節存儲;
  • REAL: 該值是一個浮點值,以8字節浮點數存儲;
  • TEXT: 該值是一個文本字符串,使用數據庫編碼(UTF-8,UTF-16BE或UTF-16LE)存儲;
  • BLOB: 值是BLOB數據塊,以輸入的數據格式進行存儲。

3.Android使用SQLite

上文已說,Android集成了SQLite數據庫,與此同時,Android還提供了使用SQLite數據庫的API,可通過這些API可很方便的進行數據庫操作。

3.1 SQLiteOpenHelper介紹

SQLiteOpenHelper是Android提供的SQLite幫助類,用于管理數據庫(包括創建、增,刪,改)和管理數據庫的版本,方便開發者操作SQLite,SQLiteOpenHelper基本方法如下(更相信請參考官方文檔https://developer.android.google.cn/reference/android/database/sqlite/SQLiteOpenHelper?hl=zh-cn)

方法名描述
onCreate()首次創建數據庫時執行該方法,如果數據庫不存在則創建,onCreate()方法在初次調用時才會被調用。重寫onCreate()方法時,生成數據表結構
onUpgrade()在需要升級數據庫時調用方法,該方法檢測數據庫傳入的版本號與當前的版本號是否相同,如果傳入的版本號高于之前的版本,觸發該方法
getReadableDatabase()創建或者打開可讀數據庫
getWritableDatabase()創建打開可讀/寫的數據庫
close()關閉所有打開的數據庫對象

onCreat和onUpgrade是開發者實現,由SQLiteOpenHelper來調用。

其中onCreat是SQLiteOpenHelper在嘗試找數據庫時,如果沒有找到則執行該方法,那么什么時候SQLiteOpenHelper去找數據庫呢?是在創建SQLiteOpenHelper實例時,還是使用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()獲取SQLiteDatabase時?

我們可以用代碼來驗證一下,我們在繼承了SQLiteOpenHelper的MySQLiteOpenHelper代碼里面添加一個flag作為標記,flag初始值是0,然后在構造函數里賦值成100,最后在onCreate中添加打印代碼。然后我們在Activity里首先只實例化MySQLiteOpenHelper,不獲取數據庫,看是否觸發了onCreate里的打印信息。之后再添加java SQLiteDatabase sqLiteDatabase= mySQLiteOpenHelper.getWritableDatabase();獲取數據,再看打印信息。

Activity代碼如下:

package com.test.sqlitedemo;import androidx.appcompat.app.AppCompatActivity;import android.database.sqlite.SQLiteDatabase; import android.os.Bundle;public class MainActivity extends AppCompatActivity {MySQLiteOpenHelper mySQLiteOpenHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mySQLiteOpenHelper=new MySQLiteOpenHelper(this,"test",1);} }

MySQLiteOpenHelper代碼如下:

package com.test.sqlitedemo;import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log;public class MySQLiteOpenHelper extends SQLiteOpenHelper {private int flag=0;/**** @param context* @param name 數據庫名稱* @param version 數據庫版本號 當想升級數據庫時,填入大于當前版本號的數*/public MySQLiteOpenHelper(Context context, String name, int version) {super(context, name, null, version);//這里賦值成100flag=100;}/**** @param db SQLiteDatabase數據庫對象*/@Overridepublic void onCreate(SQLiteDatabase db) {Log.d("MySQLiteOpenHelper", "flag="+flag);//新建數據表db.execSQL("create table translog(_id integer primary key autoincrement, transid , amount,date)");flag=50;}/**** @param db* @param oldVersion 舊版本號* @param newVersion 新版本號*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.i("MySQLiteOpenHelper", oldVersion + "------->" + newVersion);}}

驗證結果是只實例化MySQLiteOpenHelper沒有觸發onCreate里的打印信息,在獲取數據庫的時候,SQLiteOpenHelper才會調用onCreate方法,關閉應用后再打開,也不會觸發打印信息,因為數據庫已經創建了。(這里驗證半天,然后發現官網用一句話說清楚了什么時候創建數據庫:

Create a helper object to create, open, and/or manage a database. This method always returns very quickly. The database is not actually created or opened until one of getWritableDatabase() or getReadableDatabase() is called

再來看onUpgrade方法,該方法在數據庫需要升級的時候調用,當傳入SQLiteOpenHelper構造版本參數大于當前的版本時,觸發該方法。升級數據庫是開發者經常要面對的,而且多數時候在升級數據庫時不能把之前的數據全部刪掉,開發者可在onUpgrade函數里添加搬運數據的代碼,在觸發升級后執行里面的搬運邏輯。

有人可能會問了,SQLiteOpenHelper難道僅僅是幫忙檢查數據庫是否存在和升級數據庫用到?如果只是這兩個功能,雖然能幫開發者省點工作量,但并沒有省多少工作啊!別忘了一句getWritableDatabase或者getWritableDatabase就可以獲得數據庫實例,換成其他平臺操作數據庫,還得慢慢拼湊數據庫連接語句,這也省了不少工作量。其他數據庫降級等也可以通過這個類操作,更具體請參考官方文檔。

3.2 創建數據庫

了解了SQLiteOpenHelper之后,便可以開始實踐數據庫之旅了。創建數據庫代碼見上邊的onCreate里的創建SQL語句。該語句創建一個名為translog的表,用來記錄交易日志,translog表有4列,分別是主鍵id,交易單號,金額和日期,注意到除了_id設置了為integer類型(因為要設置自增長主鍵),其他列都沒指定,執行不會報錯,這是SQLite弱數據類型的好處。

db.execSQL("create table translog(_id integer primary key autoincrement, transid , amount,date)");

3.3 添加數據

往表里添加數據有兩種方法,一種使用原生SQL語句,往表里添加一條交易日志SQL語句如下

db.execSQL("INSERT INTO translog (transid, amount,date)"+ "VALUES ('955162020', 100.00,20200305)");

還有第二種也稍微簡單移動的辦法,那就是使用SQLiteDatabase對象的提供的insert(), update(),delete(),query()方法。這些方法其實是做了一層封裝,最后還是內部轉換成SQL語句完成插入數據操作。

添加數據insert(String table,String nullColumnHack,ContentValues values)有3個參數,其中:

  • 參數1 表名;
  • 參數2 空列的默認值;
  • 參數3 ContentValues類型數據;

其中第二個參數nullColumnHack是空列的默認值,但又可以填null,我們知道,SQL不允許在不指定一個列名的情況下插入,例如***INSERT INTO translog ()VALUES ()")***是錯的,如果第三個參數為空值,則會出現這種語法錯誤,第二個參數正是為了防止錯誤誕生,這樣第三個參數為空值時,則使用第二個參數作為默認字段。那為什么又可以設置為null?這是在第三個參數values不為Null并且元素的個數大于0可以填的 。這個參數的思路是,如果你懶得檢查第三個參數是否為空,那么填一個參數讓我管,如果你填了一個null不讓我管,那么你自己就要注意第三個參數不能為空。

第三個參數是ContentValues類型的數值,用法和map相似,提供了存取數據的put和get方法。注意鍵應該是表中存在的列名稱。

下面是插入代碼示例,注意到我們沒給主鍵添加值,我們已經設置主鍵是自增長列,當沒再ContentValues里給一個列put一個值時,相當于為該列添加一個null的值,主鍵自動增長,但是如果賦值了,則id設置成賦值后的值,建議讓id自動增長,自己賦值不注意的話會導致id重復而報錯。

//實例化常量值 ContentValues cValue = new ContentValues(); //添加交易單號 cValue.put("transid","9551620200307"); //添加消費金額 cValue.put("amount",100.00); //添加交易日期 cValue.put("date",2020-03-07); //調用insert()方法插入數據 db.insert("translog",null,cValue);

3.4 更新數據

更新數據當然也可用原生SQL語句然后使用execSQL() 方法可以達到目的,或者使用update()函數,函數的說明如下

int update(String table, ContentValues values, String whereClause, String[] whereArgs)
  • 參數1 表名;
  • 參數2 ContentValues類型數據;
  • 參數3 WHERE表達式(String),指定需進行數據更新的行,其中?號是占位符,如果傳遞null將更新所有行;
  • 參數4 填充第三個參數里的占位符,String[]數組類型;

例如想更新交易記錄***9551620200307***的消費金額,可用如下代碼實現

ContentValues replaceAmount = new ContentValues(); //要修改的金額 replaceAmount.put("amount","50.00"); //指定第3個參數里占位符?的內容,最后將翻譯成transid=9551620200307 String[] parms=new String[] {"9551620200307"}; //執行更新 db.update("translog", replaceAmount, "transid=?", parms);

3.5 刪除數據

經過熟悉增改函數后,發現函數都是有固定討論的,刪除函數delete和update函數參數很像,只不過少了要增加的參數,因為刪除是破壞,破壞起來簡單。

public int delete (String table, String whereClause, String[] whereArgs)
  • 參數1 表名;
  • 參數2 WHERE表達式(String),指定需進行刪除的行,其中?號是占位符,如果傳遞null將刪除所有行;
  • 參數3 填充第二個參數里的占位符,String[]數組類型;

例如想刪除交易記錄***9551620200307***,可用如下代碼實現

//指定第3個參數,也就是占位符?的內容,最后將翻譯成transid=9551620200307 String[] parms=new String[] {"9551620200307"}; //執行更新 db.delete("translog", "transid=?", parms);

3.6 查詢數據

查詢方法放到最后,因為查詢比較復雜,如果是查詢全部數據還好,否則要指定各種條件。和前面的功能一樣,查詢也有兩種方式,但要注意的是,原生查詢SQL不支持db.execSQL,而是使用單獨為查詢設置的db.rawQuery方法,rawQuery方法兩種類型,其中簡單一點的原型如下:

Cursor rawQuery (String sql, String[] selectionArgs)

其中第一個參數是SQL語句,第二個參數用于填充第一個參數里的占位符。rawQuery返回Cursor,最后再通過Cursor找到想要的查詢結果。示例代碼如下:

Cursor cursor = db.rawQuery("select * from transid",null); while(cursor.moveToNext()){int id=cursor.getInt(cursor.getColumnIndex("id");String transid=cursor.getString(cursor.getColumnIndex("transid"));String amount=cursor.getString(cursor.getColumnIndex("amount"));String date=cursor.getString(cursor.getColumnIndex("date")); }

rawQuery比較適用于簡單查詢,如果要設置更多條件,使用這個方法將會非常復雜。這個時候建議使用query方法,雖然參數比前面介紹的數據庫增刪改要多得多,但要比原生SQL查詢語句可讀性強。

來看其中一個query原型:

Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

參數說明

  • distinct:指定是否過濾結果里的重復值,true過濾,false不過濾;
  • table:表名
  • columns:指定想要查詢的列的名稱集;
  • selection:WHERE之后的條件語句,可以使用占位符
  • selectionArgs:如果selection里有占位符,使用該參數填充
  • groupBy:指定分組的列名對,指定的話結果將按照列名分組
  • having:指定分組條件,配合groupBy使用
  • orderBy:指定排序的列名
  • limit:用于限定返回結果行數

除了table必須指定,其他參數都可以設置為null,這樣等同于一句簡單的select * from table。

結束語

SQLite因性能優秀占用體積小且開源被Android采用,如果Android程序需要保存大量數據,選擇使用SQLite是一個明智的方案,Android針對SQLite封裝了簡單易用的API,其中SQLiteOpenHelper類用于創建和更新數據庫,通過SQLiteOpenHelper,開發者不用糾結于創建數據庫連接等繁瑣的操作。在Android上,既可以選擇使用原生SQL語句,也可以使用封裝好的API操作,API包含了數據庫的增刪改查基本操作,通過使用API,不僅方便開發者,也增強了程序的可讀性。不過,Android封裝的API還是有點繁瑣,目前已有大量好用的第三方庫,可以更加方便操作數據庫,這將會在后續介紹。

總結

以上是生活随笔為你收集整理的Android持久化存储(3)SQLite数据库的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。