SQLiteOpenHelper使用及原始碼分析

2021-07-11 05:34:38 字數 4450 閱讀 5357

最近研究資料庫知識,本來想接著dialog寫alertdialog,把dialog的內容寫完的。但是最近正好研究資料庫,並且沒有太多時間,就寫下這個簡單的類,跟大家分享下,加深了解。sqliteopenhelper這個類是幫助建立資料庫的。這裡的例項**裡面會有介紹

使用方法比較簡單,這裡只要複寫oncreate()方法與onupgrade()方法即可。這裡我們建立兩個表,乙個tablecontact,乙個是tablecall。這裡我通過inte***ce建立了幾個靜態常量,便於管理。如果裡面的sql語句不懂的話還是要了解下sql語句,這種基礎的還是要會的。

public

class

testsqliteopenhelper

extends

sqliteopenhelper

public

inte***ce

tablecall

public

testsqliteopenhelper(context context)

public

testsqliteopenhelper(context context, string name, sqlitedatabase.curso***ctory factory, int version)

@override

public

void

oncreate(sqlitedatabase db)

@override

public

void

onupgrade(sqlitedatabase db, int oldversion, int newversion)

}

使用的話我這裡我可以寫出如下**:

//獲取sqliteopenhelper的例項通過getwritabledatabase()獲取sqlitedatabase 的例項。

testsqliteopenhelper testsqliteopenhelper = new testsqliteopenhelper(this);

sqlitedatabase sqlitedatabase = testsqliteopenhelper.getwritabledatabase();

//這裡是插入操作。需要乙個表名和nullcolumnhack引數。這個引數處理當插入的values為空的時候的情況。當null時候插入為空不操作。如果想填入預設值就通過insert第二個引數傳入。第三個引數是個需要傳入需要的值。通過乙個hashmap來儲存乙個parcelable資料,這裡contentvalues 資料型別比較簡單,就不在詳細說明了

contentvalues values = new contentvalues();

values.put(testsqliteopenhelper.tablecontact.peoplename,"小明");

values.put(testsqliteopenhelper.tablecontact.number,"1111111");

sqlitedatabase.insert(testsqliteopenhelper.tablecontact.tablename,null,values);

當查詢時候我們可以使用如下**:

sqlitedatabase database = testsqliteopenhelper.getreadabledatabase();

string string = ;

cursor cursor = database.query(testsqliteopenhelper.tablecontact.tablename,string,

null,null,null,null,null);

cursor.movetofirst();

int namecolumnindex = cursor.getcolumnindex(testsqliteopenhelper.tablecontact.peoplename);

if (cursor != null)

log.v(">>>>>>",cursor.getstring(namecolumnindex));

cursor.close();

資料庫的查詢我就不在細說。裡面東西比較多,這裡就暫時放在一邊,以後機會我們研究sqlitedatabase這個類的時候我們在來研究具體查詢方法。

這裡基本就完成成了**的使用,但是是不是感覺每次呼叫都要不停的get各種datebase是不是比較麻煩。我們可以寫個halper類來解決這個問題。至於解決辦法我們可以生成乙個靜態內部類。我這裡僅僅寫下大概框架。實現就不在意義列舉了

public

class

testsqliteopenhelper

extends

sqliteopenhelper

......

public

static

class

usehelper

testsqliteopenhelper

mhelper;

public

usehelper(context contest)

public

void

insert()

public

curser()

.....

}

這裡我講解的比價簡單。其實sqliteopenhelper僅僅是為了幫助我們建立乙個datebase,沒有套多問題。那麼我們來研究原始碼的問題吧。到底他的呼叫週期是什麼。

先看建構函式,

public

sqliteopenhelper(context context, string name, curso***ctory factory, int version,

databaseerrorhandler errorhandler)

幾個建構函式都指向這個,忽然發現好簡單啊。這裡沒啥收穫,那麼我們就找在**呼叫。

public sqlitedatabase getwritabledatabase() 

}public sqlitedatabase getreadabledatabase()

}

明確了吧,就是getdatabaselocked()這個函式。那麼我們研究如何這個函式。

private sqlitedatabase getdatabaselocked(boolean writable)  else

if (!writable || !mdatabase.isreadonly())

}//如果正在開啟就跑出錯誤

if (misinitializing)

//好些原始碼都哎建立乙個控制代碼。也就是c中的指標,這裡感覺沒必要。

sqlitedatabase db = mdatabase;

try

} else

if (mname == null) else else

} catch (sqliteexception ex)

log.e(tag, "couldn't open " + mname

+ " for writing (will try read-only):", ex);

final string path = mcontext.getdatabasepath(mname).getpath();

db = sqlitedatabase.opendatabase(path, mfactory,

sqlitedatabase.open_readonly, merrorhandler);}}

//這個函式是個介面可以在開啟資料庫或者新建之前對資料庫進行設定。

onconfigure(db);

//獲取定期當前版本,如果是版本不一致要呼叫不同入口

final

int version = db.getversion();

if (version != mnewversion)

//設定開啟模式。

db.begintransaction();

try else else

}//配置引數

db.setversion(mnewversion);

db.settransactionsuccessful();

} finally

}//開啟資料庫

onopen(db);

if (db.isreadonly())

mdatabase = db;

return db;

} finally

}}

主要的流程都通過上面的介紹完成。要結合原始碼程式來閱讀,裡面獲取資料庫這一段跟context有關,這是設定資料庫許可權的地方,**很簡單,到底有啥用處我就沒有跟蹤。

其實這個呼叫很符合我們的預期。當沒有資料庫的時候直接呼叫oncreat()。然後判斷版本。確定公升級還是降級。

Cartographer原始碼篇 原始碼分析 1

在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...

AbstractListView原始碼分析3

normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...

Android AsyncTask原始碼分析

android中只能在主線程中進行ui操作,如果是其它子執行緒,需要借助非同步訊息處理機制handler。除此之外,還有個非常方便的asynctask類,這個類內部封裝了handler和執行緒池。本文先簡要介紹asynctask的用法,然後分析具體實現。asynctask是乙個抽象類,我們需要建立子...