如何使用SQLite
前些時(shí)候看到興趣小組里有人問“Android上SQLite的最佳實(shí)踐”是什么,好奇地搜了一下,確實(shí)沒有一個(gè)好一點(diǎn)的指導(dǎo)文檔,平時(shí)的使用也只是簡(jiǎn)單的拷貝code,并沒有深入的研究過。以下是我看到的Kevin關(guān)于其使用的心得,原文的大體的意思是:
Android例子涵蓋了一些Sqlite的基本用法,但它們并沒有深入地給出合理的使用方法,更重要的是,不合理的使用方法。大多數(shù)例子和文檔只是涉及最基本的數(shù)據(jù)庫(kù)查詢,或者教你如何創(chuàng)建一個(gè)ContentProvider。從來(lái)不提及的地方像:
? ? ? ? ·???????? 什么地方創(chuàng)建和保存SQLiteOpenHelper實(shí)例?
? ? ? ? ·???????? 可以有多少個(gè)實(shí)例?
? ? ? ? ·???????? 多線程同時(shí)訪問數(shù)據(jù)庫(kù)有沒有什么要擔(dān)心的?
基本的內(nèi)容是,你可以任意次數(shù)地連接Sqlite數(shù)據(jù)庫(kù),而且Android系統(tǒng)也支持你這樣做。Sqlite擁有文件級(jí)別的鎖,用來(lái)同步訪問和防止錯(cuò)誤。如果你只知道這些,那么,將會(huì)給你帶來(lái)很大的痛苦。開源的一個(gè)好處是,你可以深入代碼一探究竟。從代碼和一些測(cè)試中,我了解到以下事實(shí):
? ? ? ? ·???????? Sqlite擁有文件級(jí)別的鎖。許多線程可以同時(shí)讀,但只有一個(gè)可以寫。鎖阻止多個(gè)同時(shí)寫入。
? ? ? ? ·???????? Android在SQLiteDatabase中實(shí)現(xiàn)了一些java鎖來(lái)確保動(dòng)作是同步進(jìn)行。
? ? ? ? ·???????? 如果你用多個(gè)線程瘋狂地訪問數(shù)據(jù)庫(kù),你的數(shù)據(jù)庫(kù)不會(huì)(或不應(yīng)該)崩潰。
沒提到的是,如果你通過多個(gè)不同的真實(shí)連接同時(shí)寫數(shù)據(jù)庫(kù),其中的某個(gè)會(huì)失敗,它不會(huì)等到前一個(gè)完成后繼續(xù)寫入。簡(jiǎn)單地,不會(huì)寫入你的改變,更糟糕的是,你也得不到一個(gè)異常,只是在LogCat中輸出一些message,僅此而已。
SQLiteOpenHelper類做了一些有趣的事。盡管它有方法可以獲得一個(gè)只讀的連接和可讀寫的連接,但實(shí)質(zhì)上它們是同一個(gè)連接。假設(shè)沒有文件寫錯(cuò)誤的話,只讀的連接實(shí)質(zhì)上就是一個(gè)可讀寫的連接。有趣吧。因此,如果你的app中使用一個(gè)helper的話,即便從多線程中使用,你也從未使用多個(gè)連接。
同樣,一個(gè)helper中只有一個(gè)SQLiteDatabase的實(shí)例,這個(gè)實(shí)例中實(shí)現(xiàn)了一些java鎖。因此,當(dāng)你正在執(zhí)行數(shù)據(jù)庫(kù)的操作時(shí),其它db的操作都將鎖定。即便是你使用多個(gè)線程來(lái)做這些事以便優(yōu)化數(shù)據(jù)庫(kù)的性能,壞消息,沒有什么用。
按照我的認(rèn)識(shí),SQLite工作的方式,基本上不可能會(huì)破壞你的數(shù)據(jù)庫(kù),除非代碼里有bug或者有硬件問題。
因此,我推薦這樣使用:創(chuàng)建一個(gè)SQLiteOpenHelper靜態(tài)對(duì)象。什么時(shí)候去close它呢?不需要。當(dāng)app關(guān)閉,它會(huì)自動(dòng)釋放文件引用。
但是,會(huì)不會(huì)有“close() was never explicitly called on database”異常呢?
如果你注意的話,當(dāng)連接掛在那里的時(shí)候,你沒有得到那個(gè)異常。你只是在連接已經(jīng)建立,而你又嘗試打開另一個(gè)時(shí)才會(huì)有異常。因此,你只需要打開一次連接。
像這樣來(lái)使用:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
??? private static DatabaseHelper instance;
?
??? public static synchronized DatabaseHelper getHelper(Context context)
??? {
??????? if (instance == null)
???? ???????instance = new DatabaseHelper(context);
?
??????? return instance;
??? }
//Other stuff...?
}
?
就這些。。。
原文地址:
http://www.touchlab.co/blog/android-sqlite-locking/
http://www.touchlab.co/blog/single-sqlite-connection/
總結(jié)
以上是生活随笔為你收集整理的如何使用SQLite的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: $@等特定shell变量的含义
- 下一篇: javascript js jquery