Android編程之SQLite數(shù)據(jù)庫操作方法詳解
本文實(shí)例講述了Android SQLite數(shù)據(jù)庫操作方法。分享給大家供大家參考,具體如下:
SQLite and Android
SQLite簡介
SQLite是一個(gè)非常流行的嵌入式數(shù)據(jù)庫,它支持SQL語言,并且只利用很少的內(nèi)存就有很好的性能。此外,它還是開源的,任何人都可以使用它。
SQLite由以下幾個(gè)組件組成:SQL編譯器、內(nèi)核、后端以及附件。SQLite通過利用虛擬機(jī)和虛擬數(shù)據(jù)庫引擎(VDBE),使調(diào)試、修改和擴(kuò)展SQLite的內(nèi)核變得更加方便。
SQLite支持的數(shù)據(jù)類型包括:
1. TEXT (類似于Java的String)
2. INTEGER (類似于Java的long)
3. REAL (類似于Java的Double)
更多SQLite數(shù)據(jù)類型知識(shí)可以參考前面相關(guān)文章入:詳解SQLite中的數(shù)據(jù)類型
SQLite In Android
Android在運(yùn)行時(shí)集成了SQLite,因此在Android中使用SQLite數(shù)據(jù)庫并不需要安裝過程和獲取數(shù)據(jù)庫使用權(quán)限,你只需要定義創(chuàng)建和更新數(shù)據(jù)庫的語句即可,其他的會(huì)由Android平臺(tái)替你搞定。
操作SQLite數(shù)據(jù)庫通常意味著操作文件系統(tǒng),這種操作還是比較耗時(shí)的,因此建議將數(shù)據(jù)庫操作異步執(zhí)行。
你的應(yīng)用創(chuàng)建一個(gè)SQLite數(shù)據(jù)庫,數(shù)據(jù)在默認(rèn)情況下,存儲(chǔ)在/DATA/data/APP_NAME/databases/FILENAME。這里DATA是Environment.getDataDirectory()方法返回的值,APP_NAME是你的應(yīng)用包名
Android開發(fā)中使用SQLite數(shù)據(jù)庫
Activity可以使用Content Provider或者 Service訪問一個(gè)數(shù)據(jù)庫。
創(chuàng)建數(shù)據(jù)庫
Android不自動(dòng)提供數(shù)據(jù)庫。在Android應(yīng)用程序中使用SQLite,必須自己創(chuàng)建數(shù)據(jù)庫,然后創(chuàng)建表、索引、填充數(shù)據(jù)。Android提供了一個(gè)SQLiteOpenHelper幫助你創(chuàng)建一個(gè)數(shù)據(jù)庫,你只要繼承 SQLiteOpenHelper 類,就可以輕松的創(chuàng)建數(shù)據(jù)庫。
SQLiteOpenHelper 類根據(jù)開發(fā)應(yīng)用程序的需要,封裝了創(chuàng)建和更新數(shù)據(jù)庫使用的邏輯。SQLiteOpenHelper 的子類,至少需要實(shí)現(xiàn)三個(gè)方法:
構(gòu)造函數(shù),調(diào)用父類SQLiteOpenHelper的構(gòu)造函數(shù)。這個(gè)方法需要四個(gè)參數(shù):上下文環(huán)境,數(shù)據(jù)庫名字,一個(gè)可選的游標(biāo)工廠(通常是NULL),一個(gè)代表你正在使用的數(shù)據(jù)庫模型版本的整數(shù)。
onCreate()方法,它需要一個(gè)SQLiteDatabase對(duì)象作為參數(shù),根據(jù)需要對(duì)這個(gè)對(duì)象填充表和初始化數(shù)據(jù)。
onUpgrade()方法,它需要三個(gè)參數(shù),一個(gè)SQLiteDatabase對(duì)象,一個(gè)舊的版本號(hào)和一個(gè)新的版本號(hào),這樣你就可以清楚如何把一個(gè)數(shù)據(jù)庫從舊的模型轉(zhuǎn)變?yōu)樾碌哪P汀?/p>
首先,定義需要?jiǎng)?chuàng)建的表結(jié)構(gòu),使用類來進(jìn)行抽象,這里示例定義一個(gè)新浪微薄的帳號(hào)類:
public class AccountTable { public static final String TABLE_NAME = "account_table"; public static final String UID = "uid"; public static final String USERNAME = "username"; public static final String USERNICK = "usernick"; public static final String AVATAR_URL = "avatar_url"; public static final String PORTRAIT = "portrait"; public static final String OAUTH_TOKEN = "oauth_token"; public static final String OAUTH_TOKEN_SECRET = "oauth_token_secret"; public static final String INFOJSON = "json"; }
下面代碼展示了如何繼承SQLiteOpenHelper創(chuàng)建數(shù)據(jù)庫,推薦使用單例類:
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import org.qii.weiciyuan.support.database.table.*; class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper singleton = null; private static final String DATABASE_NAME = "weibo.db"; private static final int DATABASE_VERSION = 16; static final String CREATE_ACCOUNT_TABLE_SQL = "create table " + AccountTable.TABLE_NAME + "(" + AccountTable.UID + " integer primary key autoincrement," + AccountTable.OAUTH_TOKEN + " text," + AccountTable.OAUTH_TOKEN_SECRET + " text," + AccountTable.PORTRAIT + " text," + AccountTable.USERNAME + " text," + AccountTable.USERNICK + " text," + AccountTable.AVATAR_URL + " text," + AccountTable.INFOJSON + " text" + ");"; DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_ACCOUNT_TABLE_SQL); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch (oldVersion) { default: deleteAllTable(db); onCreate(db); } } public static synchronized DatabaseHelper getInstance() { if (singleton == null) { singleton = new DatabaseHelper(GlobalContext.getInstance()); } return singleton; } private void deleteAllTable(SQLiteDatabase db) { db.execSQL("DROP TABLE IF EXISTS " + AccountTable.TABLE_NAME); } }
增刪改查數(shù)據(jù)庫
因?yàn)镾QLite支持標(biāo)準(zhǔn)的SQL語句,因此我們可以用標(biāo)準(zhǔn)SQL語句才增刪改查數(shù)據(jù)庫,推薦使用占位符的sql語句,看起來更加清爽,下面是我的代碼示例:
package com.hw.droid.hwcatalog; public class DatabaseManager { private static DatabaseManager singleton = null; private SQLiteDatabase wsd = null; private SQLiteDatabase rsd = null; private DatabaseManager() { } public static DatabaseManager getInstance(Context context) { if (singleton == null) { synchronized (DatabaseManager.class) { if (singleton == null) { DatabaseHelper databaseHelper = DatabaseHelper.getInstance(context); singleton = new DatabaseManager(); singleton.wsd = databaseHelper.getWritableDatabase(); singleton.rsd = databaseHelper.getReadableDatabase(); } } } return singleton; } public void initAccountTable(List<AccountData> listDatas) { if (listDatas == null || listDatas.size() <= 0) { return; } wsd.beginTransaction(); try { for (AccountData data : listDatas) { insertAccountTable(data); } wsd.setTransactionSuccessful(); } finally { wsd.endTransaction(); } } private void insertAccountTable(AccountData accData) { String sql = "insert into " + AccountTable.TABLE_NAME + "(" + AccountTable.USERNAME + ", " + AccountTable.USERNICK + ", " + AccountTable.AVATAR_URL + ", " + AccountTable.PORTRAIT + ", " + AccountTable.OAUTH_TOKEN + ", " + AccountTable.OAUTH_TOKEN_SECRET + ", " + AccountTable.INFOJSON + " " + ")" + " values(?, ?, ?, ?, ?, ?, ?)"; wsd.execSQL(sql, new Object[] { accData.getUserName(), accData.getUserNick(), accData.getUrl(), accData.getPort(), accData.getToken(), accData.getSecret(), accData.getJson(), accData.getThreads(), }); } public List<AccountData> getAccountDatas() { List<AccountData> listDatas = selectAccountData(); return listDatas; } private List<AccountData> selectAccountData() { List<AccountData> listAccountData = new ArrayList<AccountData>(); String querySql = "select " + AccountTable.USERNAME + ", " + AccountTable.USERNICK + ", " + AccountTable.AVATAR_URL + ", " + AccountTable.PORTRAIT + ", " + AccountTable.OAUTH_TOKEN + ", " + AccountTable.OAUTH_TOKEN_SECRET + ", " + AccountTable.INFOJSON " " + " from " + BbsForumsTable.TABLE_NAME; Cursor cursor = rsd.rawQuery(querySql, null); if (cursor.moveToFirst()) { do { AccountData data = new AccountData(); data.setUserName(cursor.getString(cursor.getColumnIndex(AccountTable.USERNAME))); data.setUserNick(cursor.getString(cursor.getColumnIndex(AccountTable.USERNICK))); data.setUrl(cursor.getString(cursor.getColumnIndex(AccountTable.AVATAR_URL))); data.setPort(cursor.getString(cursor.getColumnIndex(AccountTable.PORTRAIT))); data.setToken(cursor.getString(cursor.getColumnIndex(AccountTable.OAUTH_TOKEN))); data.setSecret(cursor.getString(cursor.getColumnIndex(AccountTable.OAUTH_TOKEN_SECRET))); data.setJson(cursor.getString(cursor.getColumnIndex(AccountTable.INFOJSON))); listAccountData.add(data); } while (cursor.moveToNext()); } cursor.close(); return listAccountData; } public void deleteBbsDatas() { String delSql = "delete from " + AccountTable.TABLE_NAME; wsd.execSQL(delSql); } }
事物(DBTransaction)
Android中經(jīng)常會(huì)用到數(shù)據(jù)庫緩存,特別是wifi情況下遇到數(shù)據(jù)不一致情況需要更新緩存數(shù)據(jù),這個(gè)時(shí)候就需要用到事物處理,保證操作的完整性和速度。Android中使用SQLite保證事務(wù)完整性示例如下:
public void initAccountTable(List<AccountData> listDatas) { if (listDatas == null || listDatas.size() <= 0) { return; } wsd.beginTransaction(); try { for (AccountData data : listDatas) { insertAccountTable(data); } wsd.setTransactionSuccessful(); } finally { wsd.endTransaction(); } }
通過beginTransaction()開啟事務(wù),endTransaction()結(jié)束事務(wù),并且設(shè)置事務(wù)執(zhí)行成功標(biāo)識(shí)setTransactionSuccessful().
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android操作SQLite數(shù)據(jù)庫技巧總結(jié)》、《Android數(shù)據(jù)庫操作技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android文件操作技巧匯總》、《Android開發(fā)入門與進(jìn)階教程》、《Android資源操作技巧匯總》、《Android視圖View技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android SQLite事務(wù)處理結(jié)合Listview列表顯示功能示例
- Android開發(fā)筆記SQLite優(yōu)化記住密碼功能
- Android利用listview控件操作SQLite數(shù)據(jù)庫實(shí)例
- Android批量插入數(shù)據(jù)到SQLite數(shù)據(jù)庫的方法
- Android SQLite數(shù)據(jù)庫基本操作方法
- Android使用SQLite數(shù)據(jù)庫的示例
- android SQLite數(shù)據(jù)庫總結(jié)
- Android SQLite數(shù)據(jù)庫版本升級(jí)的管理實(shí)現(xiàn)
相關(guān)文章
關(guān)于Android WebView的loadData方法的注意事項(xiàng)分析
本篇文章是對(duì)Android中WebView的loadData方法的注意事項(xiàng)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android10 啟動(dòng)之SystemServer源碼分析
這篇文章主要為大家介紹了Android10 啟動(dòng)之SystemServer源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Android App中實(shí)現(xiàn)簡單的刮刮卡抽獎(jiǎng)效果的實(shí)例詳解
這篇文章主要介紹了Android App中實(shí)現(xiàn)簡單的刮刮卡抽獎(jiǎng)效果的實(shí)例詳解,文中主要借助Bitmap的canvas.drawPath的api來實(shí)現(xiàn),需要的朋友可以參考下2016-03-03Android實(shí)現(xiàn)倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)倒計(jì)時(shí)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10簡介Android應(yīng)用中sharedPreferences類存儲(chǔ)數(shù)據(jù)的用法
這篇文章主要介紹了Android應(yīng)用中使用sharedPreferences類存儲(chǔ)數(shù)據(jù)的方法,文中舉了用SharedPreferences保存數(shù)據(jù)和讀取數(shù)據(jù)的例子,需要的朋友可以參考下2016-02-02淺談Android中Drawable使用知識(shí)總結(jié)
本篇文章主要介紹了淺談Android中Drawable使用知識(shí)總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12android中ViewPager結(jié)合Fragment進(jìn)行無限滑動(dòng)
本篇文章中主要介紹了android中ViewPager結(jié)合Fragment進(jìn)行無限滑動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03Android手機(jī)上同時(shí)安裝正式包與測(cè)試包的方法
這篇文章主要給大家介紹了關(guān)于Android手機(jī)上同時(shí)安裝正式包與測(cè)試包的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02