天天看點

使用iOS原生sqlite3架構對sqlite資料庫進行操作

      sqlite資料庫是一種小型資料庫,由于其小巧與簡潔,在移動開發領域應用深廣,sqlite資料庫有一套完備的sqlite語句進行管理操作,一些常用的語句和可視化的開發工具在上篇部落格中有介紹,位址如下:

      在ios的原生開發架構中可以對sqlite資料庫進行很好的支援,這個架構中采用c風格且通過指針移動進行資料的操作,使用起來有些不便,我們可以對一些資料庫的常用操作進行一些面向對象的封裝。

    libsqlite3是對sqlite資料庫進行操作的系統庫,在使用前,我們需要先導入,點選xcode的build phases标簽,展開link binary with libraries,點選+号,在彈出的視窗中搜尋libsqlite3.0,将其導入進工程,過程如下圖:

使用iOS原生sqlite3架構對sqlite資料庫進行操作
使用iOS原生sqlite3架構對sqlite資料庫進行操作

在需要操作sqlite資料的檔案中導入如下頭檔案:

<a href="http://my.oschina.net/u/2340880/blog/601802#">?</a>

1

<code>#import &lt;sqlite3.h&gt;</code>

資料庫檔案的操作是由一個sqlite3類型的指針操作管理的,如下方法進行資料庫的打開:

2

<code>sqlite3 *sqlite;</code>

<code>sqlite3_open(databaepath, &amp;sqlite)</code>

sqlite3_open方法傳回一個int值,實際上,在使用libsqlite3架構中的大多方法時都會傳回一個int值,這個int值代表着方法執行的相應結果狀态,這些狀态再sqlite3.h檔案中通過宏來定義,列舉如下:

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<code>#define sqlite_ok           0   //操作成功</code>

<code>/* 以下是錯誤代碼 */</code>

<code>#define sqlite_error        1   /* sql資料庫錯誤或者丢失*/</code>

<code>#define sqlite_internal     2   /* sql内部邏輯錯誤 */</code>

<code>#define sqlite_perm         3   /* 沒有通路權限 */</code>

<code>#define sqlite_abort        4   /* 回調請求終止 */</code>

<code>#define sqlite_busy         5   /* 資料庫檔案被鎖定 */</code>

<code>#define sqlite_locked       6   /* 資料庫中有表被鎖定 */</code>

<code>#define sqlite_nomem        7   /* 配置設定空間失敗 */</code>

<code>#define sqlite_readonly     8   /* 企圖向隻讀屬性的資料庫中做寫操作 */</code>

<code>#define sqlite_interrupt    9   /* 通過sqlite3_interrupt()方法終止操作*/</code>

<code>#define sqlite_ioerr       10   /* 磁盤發生錯誤 */</code>

<code>#define sqlite_corrupt     11   /* 資料庫磁盤格式不正确 */</code>

<code>#define sqlite_notfound    12   /* 調用位置操作碼 */</code>

<code>#define sqlite_full        13   /* 由于資料庫已滿造成的添加資料失敗 */</code>

<code>#define sqlite_cantopen    14   /* 不法打開資料庫檔案 */</code>

<code>#define sqlite_protocol    15   /* 資料庫鎖協定錯誤 */</code>

<code>#define sqlite_empty       16   /* 資料庫為空 */</code>

<code>#define sqlite_schema      17   /* 資料庫模式更改 */</code>

<code>#define sqlite_toobig      18   /* 字元或者二進制資料超出長度 */</code>

<code>#define sqlite_constraint  19   /* 違反協定終止 */</code>

<code>#define sqlite_mismatch    20   /* 資料類型不比對 */</code>

<code>#define sqlite_misuse      21   /* 庫使用不當 */</code>

<code>#define sqlite_nolfs       22   /* 使用不支援的作業系統 */</code>

<code>#define sqlite_auth        23   /* 授權拒絕 */</code>

<code>#define sqlite_format      24   /* 輔助資料庫格式錯誤 */</code>

<code>#define sqlite_range       25   /* sqlite3_bind 第二個參數超出範圍 */</code>

<code>#define sqlite_notadb      26   /* 打開不是資料庫的檔案 */</code>

<code>#define sqlite_notice      27   /* 來自sqlite3_log()的通知 */</code>

<code>#define sqlite_warning     28   /* 來自sqlite3_log() 的警告*/</code>

<code>#define sqlite_row         100  /* sqlite3_step() 方法準備好了一行資料 */</code>

<code>#define sqlite_done        101  /* sqlite3_step() 已完成執行*/</code>

執行非查詢類的語句,例如建立,添加,删除等操作,使用如下方法:

<code>char</code> <code>* err;</code>

<code>sqlite3 *sql;</code>

<code>sqlite3_exec(sql, sqlstr, null, null, &amp;err);</code>

sqlite3_exec方法中第一個參數為成功執行了打開資料庫操作的sqlite3指針,第二個參數為要執行的sql語句,最後一個參數為錯誤資訊字元串。

執行查詢語句的方法比較複雜,通過如下方法:

<code>    </code><code>sqlite3 * sqlite;</code>

<code>    </code><code>sqlite3_stmt *stmt =nil;</code>

<code>    </code><code>int</code> <code>code = sqlite3_prepare_v2(sqlite, sqlstr, -1, &amp;stmt, null);</code>

<code>     </code><code>while</code> <code>(sqlite3_step(stmt)==sqlite_row) {</code>

<code>         </code><code>char</code> <code>* cstring =(</code><code>char</code><code>*)sqlite3_column_text(stmt, 0);</code>

<code>         </code><code>nsstring * value = [nsstring stringwithcstring:cstring?cstring:</code><code>"null"</code> <code>encoding:nsutf8stringencoding];</code>

<code>         </code><code>nsnumber * value = [nsnumber numberwithlonglong:sqlite3_column_int64(stmt, 1)];</code>

<code>        </code><code>}</code>

<code>         </code><code>sqlite3_finalize(stmt);</code>

stmt是一個資料位置指針,标記查詢到數庫的資料位置,sqlite3_prepare_v2()方法進行資料庫查詢的準備工作,第一個參數為成功打開的資料庫指針,第二個參數為要執行的查詢語句,第三個參數為sqlite3_stmt指針的位址,這個方法也會傳回一個int值,作為标記狀态是否成功。

sqlite3_step方法對stmt指針進行移動,會逐行進行移動,這個方法會傳回一個int值,如果和sqlite_row宏對應,則表明有此行資料,可以通過while循環來對資料進行讀取。

sqlite3_column_xxx()是取行中每一列的資料,根據資料類型的不同,sqlite3_column_xxx()有一系列對應的方法,這個方法中第一個參數是stmt指針,第二個參數為列序号。

sqlite3_finalize()方法對stmt指針進行關閉。

        網上不乏有許多優秀的第三方sqlite資料庫使用架構,ffdm就是其中之一,并且apple自帶的coredata也十分優秀。這篇部落格中所述内容并不全面,代碼也并不十分完善健壯,封裝出來的代碼除了能夠完成基本的資料庫操作外,更多主要是對設計思路的示例。

        為了便于使用,在設計時,我們盡量将libsqlite3中的方法不暴漏在使用層,通過面向應用的接口來進行方法的設計,設計思路類圖如下:

使用iOS原生sqlite3架構對sqlite資料庫進行操作

圖中,檔案管理中心對檔案進行存取删改管理,不暴漏在外,資料庫管理中心負責對資料庫的建立,删除打開等操作,具體的資料操作由資料庫操作對象來完成。

        檔案管理中心主要負責對資料庫檔案的存取,可以實作如下方法:

yhbasecechecenter.h

<code>/**</code>

<code> </code><code>*  @brief 擷取資料庫方法的位址</code>

<code> </code><code>*</code>

<code> </code><code>*  @return 位址字元串</code>

<code> </code><code>*/</code>

<code>-(nsstring *)getdatabasefilepath;</code>

<code> </code><code>*  @brief 擷取某個資料庫的大小</code>

<code> </code><code>*  @param name 資料庫名稱</code>

<code> </code><code>*  @return 檔案大小 機關m</code>

<code>-(</code><code>float</code><code>)getsizefromdatabasename:(nsstring *)name;</code>

yhbasecechecenter.m

<code>-(nsstring *)getdatabasefilepath{</code>

<code>    </code><code>return</code> <code>nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes).firstobject;</code>

<code>}</code>

<code>-(</code><code>float</code><code>)getsizefromdatabasename:(nsstring *)name{</code>

<code>    </code><code>nsstring * path = [nsstring stringwithformat:@</code><code>"/%@/%@"</code><code>,nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes).firstobject,name];</code>

<code>    </code><code>return</code>  <code>[self filesizeatpath:path]/(1024.0*1024.0);</code>

<code>//擷取檔案大小</code>

<code>- (</code><code>long</code> <code>long</code><code>) filesizeatpath:(nsstring*) filepath{</code>

<code>    </code><code>nsfilemanager* manager = [nsfilemanager defaultmanager];</code>

<code>    </code><code>if</code> <code>([manager fileexistsatpath:filepath]){</code>

<code>        </code><code>return</code> <code>[[manager attributesofitematpath:filepath error:nil] filesize];</code>

<code>    </code><code>}</code>

<code>    </code><code>return</code> <code>0;</code>

在ios系統中因為其沙盒結構的限制,資料庫必須方法documents目錄下才能正常打開使用。

        資料庫管理中心主要負責對資料庫的宏觀操作,采用類方法的設計模式,如下

yhbasesqlitemanager.h

<code> </code><code>*  @brief 打開一個資料庫 如果不存在則會建立</code>

<code> </code><code>*  @return 資料庫操作對象 如果建立失敗會傳回nil</code>

<code>+(yhbasesqlitecontext *)opensqlitewithname:(nsstring *)name;</code>

<code> </code><code>*  @brief 擷取資料庫檔案的大小 機關m</code>

<code> </code><code>*  @param database 資料庫上下文對象</code>

<code> </code><code>*  @return 資料庫檔案大小</code>

<code>+(</code><code>float</code><code>)getsizeofdatabase:(yhbasesqlitecontext *)database;</code>

<code> </code><code>*  @param databasename 資料庫名稱</code>

<code>+(</code><code>float</code><code>)getsizeofdatabasename:(nsstring *)databasename;</code>

<code> </code><code>*  @brief 删除所有資料庫</code>

<code>+(</code><code>void</code><code>)removedatabase;</code>

 yhbasesqlitemanager.m

<code>+(yhbasesqlitecontext *)opensqlitewithname:(nsstring *)name{</code>

<code>    </code> 

<code>    </code><code>nsstring * path =  [[yhbasecechecenter sharedthesingletion]getdatabasefilepath];</code>

<code>    </code><code>yhbasesqlitecontext * context = [[yhbasesqlitecontext alloc]init];</code>

<code>    </code><code>context.name = name;</code>

<code>    </code><code>bool</code> <code>success = [context opendatabaewithname:[nsstring stringwithformat:@</code><code>"%@/%@"</code><code>,path,name]];</code>

<code>    </code><code>if</code> <code>(success) {</code>

<code>        </code><code>return</code> <code>context;</code>

<code>    </code><code>}</code><code>else</code><code>{</code>

<code>        </code><code>return</code> <code>nil;</code>

<code>+(</code><code>float</code><code>)getsizeofdatabase:(yhbasesqlitecontext *)database{</code>

<code>    </code><code>return</code> <code>[[yhbasecechecenter sharedthesingletion]getsizefromdatabasename:database.name];</code>

<code>+(</code><code>float</code><code>)getsizeofdatabasename:(nsstring *)databasename{</code>

<code>    </code><code>return</code> <code>[[yhbasecechecenter sharedthesingletion]getsizefromdatabasename:databasename];</code>

<code>+(</code><code>void</code><code>)removedatabase{</code>

<code>    </code><code>return</code> <code>[[yhbasecechecenter sharedthesingletion]removecachefrompath:path];</code>

        将操作資料庫的核心方法封裝在這個類中:

yhbasesqlitecontext.h

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

<code> </code><code>*操作的資料庫名稱</code>

<code>@property(nonatomic,strong)nsstring * name;</code>

<code> </code><code>*内含sqlite3 對象</code>

<code>@property(nonatomic,assign)sqlite3 * sqlite3_db;</code>

<code> </code><code>* @brief 打開一個資料庫 不存在則建立</code>

<code> </code><code>* @param path 資料庫路徑</code>

<code> </code><code>* @return 是否操作成功</code>

<code>-(</code><code>bool</code><code>)opendatabaewithname:(nsstring *)path;</code>

<code> </code><code>*  @brief 再資料庫中建立一張表 如果已經存在 會傳回錯誤資訊</code>

<code> </code><code>*  @param name 表的名稱</code>

<code> </code><code>*  @prarm dic 表中的鍵 其中字典中需傳入 鍵名:類型  類型的宏定義在yhbasesqltypeheader.h中</code>

<code> </code><code>*  @param callback 結果回調</code>

<code>-(</code><code>void</code><code>)createtablewithname:(nsstring *)name</code>

<code>            </code><code>keysdictionary:(nsdictionary&lt;nsstring*,nsstring*&gt; *) dic</code>

<code>                  </code><code>callback:(</code><code>void</code> <code>(^)(yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 向表中添加一條資料</code>

<code> </code><code>*  @param datadic 添加資料的鍵值對</code>

<code> </code><code>*  @param name 插入表的名稱</code>

<code> </code><code>*  @complete 回調</code>

<code>-(</code><code>void</code><code>)insertdata:(nsdictionary&lt;nsstring *,id&gt;*)datadic</code>

<code>        </code><code>intotable:(nsstring *)name</code>

<code>         </code><code>callback:(</code><code>void</code> <code>(^)(yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 向表中添加一個鍵</code>

<code> </code><code>*  @param kname 添加的鍵</code>

<code> </code><code>*  @prarm type 類型</code>

<code> </code><code>*  @prarm tablename 表名稱</code>

<code> </code><code>*  @prarm complete 結果回調</code>

<code>-(</code><code>void</code><code>)addkey:(nsstring *)kname</code>

<code>      </code><code>keytype:(nsstring *)type</code>

<code>    </code><code>intotable:(nsstring *)tablename</code>

<code>     </code><code>callback:(</code><code>void</code><code>(^)(yhbasesqlerror *error))complete;</code>

<code> </code><code>*  @brief 修改資料</code>

<code> </code><code>*  @param datadic 新的鍵值</code>

<code> </code><code>*  @param wlstr 條件字元串 一般通過主鍵找到對應資料修改 可以為nil</code>

<code> </code><code>*  @param complete 結果回調</code>

<code>-(</code><code>void</code><code>)update:(nsdictionary&lt;nsstring*,id&gt; *)datadic</code>

<code>      </code><code>intable:(nsstring *)tablename</code>

<code>  </code><code>whilestring:(nsstring *)wlstr</code>

<code>     </code><code>callback:(</code><code>void</code><code>(^)(yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 删除資料</code>

<code> </code><code>*  @param tablename 表名</code>

<code> </code><code>*  @param wlstr 條件字元串 一般通過主鍵找到對應資料删除 可以為nil 不傳這個參數将删除所有資料</code>

<code>-(</code><code>void</code><code>)deletedatafromtable:(nsstring *)tablename</code>

<code>               </code><code>wherestring:(nsstring *)wlstr</code>

<code>                  </code><code>callback:(</code><code>void</code><code>(^)(yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 删除一張表</code>

<code>-(</code><code>void</code><code>)droptable:(nsstring *)tablename</code>

<code>        </code><code>callback:(</code><code>void</code><code>(^)(yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 查詢資料</code>

<code> </code><code>*  @param keys 要查詢的鍵值 及其對應的資料類型 可以為nil則查詢全部</code>

<code> </code><code>*  @param orderkey 進行排序的鍵值 可以為nil 則不排序</code>

<code> </code><code>*  @param type 排序方式 在yhbasesqltypeheader中有宏定義</code>

<code> </code><code>*  @param wlstr 查詢條件 同于查詢單個資料</code>

<code> </code><code>*  @param complete dataarray為查詢到的資料 其内為字典</code>

<code>-(</code><code>void</code><code>)selectkeys:(nsarray&lt;nsdictionary *&gt; *)keys</code>

<code>        </code><code>fromtable:(nsstring*)tablename</code>

<code>          </code><code>orderby:(nsstring *)orderkey</code>

<code>        </code><code>ordertype:(nsstring *)type</code>

<code>         </code><code>whilestr:(nsstring *)wlstr</code>

<code>         </code><code>callback:(</code><code>void</code><code>(^)(nsarray&lt;nsdictionary *&gt; * dataarray,yhbasesqlerror * error))complete;</code>

<code> </code><code>*  @brief 關閉資料庫上下文操作</code>

<code> </code><code>*  調用此方法後 這個context對象将不再有效 如果再需要使用 需要yhbasesqlitemanager中的類方法再次傳回</code>

<code>-(</code><code>void</code><code>)closecontext;</code>

yhbasesqlitecontext.m

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

<code>-(</code><code>bool</code><code>)opendatabaewithname:(nsstring *)path{</code>

<code>    </code><code>if</code> <code>(sqlite3_open([path utf8string], &amp;_sqlite3_db)!=sqlite_ok) {</code>

<code>        </code><code>sqlite3_close(_sqlite3_db);</code>

<code>        </code><code>_sqlite3_db=nil;</code>

<code>        </code><code>return</code> <code>no;</code>

<code>        </code><code>return</code> <code>yes;</code>

<code>-(</code><code>void</code><code>)createtablewithname:(nsstring *)name keysdictionary:(nsdictionary&lt;nsstring *,nsstring *&gt; *)dic callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>nsmutablestring * keys = [[nsmutablestring alloc]init];</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;dic.allkeys.count; i++) {</code>

<code>        </code><code>nsstring * key = dic.allkeys[i];</code>

<code>        </code><code>if</code> <code>(i&lt;dic.allkeys.count-1) {</code>

<code>            </code><code>[keys appendformat:@</code><code>"%@ %@,"</code><code>,key,[dic objectforkey:key]];</code>

<code>        </code><code>}</code><code>else</code><code>{</code>

<code>            </code><code>[keys appendformat:@</code><code>"%@ %@"</code><code>,key,[dic objectforkey:key]];</code>

<code>    </code><code>nsstring * sqlstr = [nsstring stringwithformat:@</code><code>"create table %@(%@)"</code><code>,name,keys];</code>

<code>    </code><code>[self runsql:sqlstr callback:^(yhbasesqlerror * error) {</code>

<code>        </code> 

<code>        </code><code>if</code> <code>(complete) {</code>

<code>            </code><code>complete(error);</code>

<code>    </code><code>}];</code>

<code>-(</code><code>void</code><code>)insertdata:(nsdictionary&lt;nsstring *,id&gt; *)datadic intotable:(nsstring *)name callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>nsmutablestring * values = [[nsmutablestring alloc]init];</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;datadic.allkeys.count; i++) {</code>

<code>        </code><code>nsstring * key = datadic.allkeys[i];</code>

<code>        </code><code>if</code> <code>(i&lt;datadic.count-1) {</code>

<code>            </code><code>[keys appendformat:@</code><code>"%@,"</code><code>,key];</code>

<code>            </code><code>[values appendformat:@</code><code>"\"%@\","</code><code>,[datadic objectforkey:key]];</code>

<code>            </code><code>[keys appendformat:@</code><code>"%@"</code><code>,key];</code>

<code>            </code><code>[values appendformat:@</code><code>"\"%@\""</code><code>,[datadic objectforkey:key]];</code>

<code>    </code><code>nsstring * sqlstr = [nsstring stringwithformat:@</code><code>"insert into %@(%@) values(%@)"</code><code>,name,keys,values];</code>

<code>    </code><code>[self runsql:sqlstr callback:^(yhbasesqlerror *error) {</code>

<code>-(</code><code>void</code><code>)addkey:(nsstring *)kname keytype:(nsstring *)type intotable:(nsstring *)tablename callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>nsstring * sqlstr = [nsstring stringwithformat:@</code><code>"alter table %@ add %@ %@"</code><code>,tablename,kname,type];</code>

<code>-(</code><code>void</code><code>)update:(nsdictionary&lt;nsstring *,id&gt; *)datadic intable:(nsstring *)tablename whilestring:(nsstring *)wlstr callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>nsmutablestring * sqlstr = [[nsmutablestring alloc]init];</code>

<code>    </code><code>[sqlstr appendformat:@</code><code>"update %@ set "</code><code>,tablename];</code>

<code>        </code><code>if</code> <code>(i&lt;datadic.allkeys.count-1) {</code>

<code>            </code><code>[sqlstr appendformat:@</code><code>"%@=\"%@\","</code><code>,key,[datadic objectforkey:key]];</code>

<code>            </code><code>[sqlstr appendformat:@</code><code>"%@=\"%@\""</code><code>,key,[datadic objectforkey:key]];</code>

<code>            </code><code>if</code> <code>(wlstr!=nil) {</code>

<code>                </code><code>[sqlstr appendformat:@</code><code>" where %@"</code><code>,wlstr];</code>

<code>            </code><code>}</code>

<code>-(</code><code>void</code><code>)deletedatafromtable:(nsstring *)tablename wherestring:(nsstring *)wlstr callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>[sqlstr appendformat:@</code><code>"delete from %@"</code><code>,tablename];</code>

<code>    </code><code>if</code> <code>(wlstr!=nil) {</code>

<code>        </code><code>[sqlstr appendformat:@</code><code>" where %@"</code><code>,wlstr];</code>

<code>-(</code><code>void</code><code>)droptable:(nsstring *)tablename callback:(</code><code>void</code> <code>(^)(yhbasesqlerror *))complete{</code>

<code>    </code><code>nsstring * sqlstr = [nsstring stringwithformat:@</code><code>"drop table %@"</code><code>,tablename];</code>

<code>-(</code><code>void</code><code>)selectkeys:(nsarray&lt;nsdictionary *&gt; *)keys fromtable:(nsstring *)tablename orderby:(nsstring *)orderkey ordertype:(nsstring *)type whilestr:(nsstring *)wlstr callback:(</code><code>void</code> <code>(^)(nsarray&lt;nsdictionary *&gt; *, yhbasesqlerror *))complete{</code>

<code>    </code><code>[sqlstr appendformat:@</code><code>"select"</code><code>];</code>

<code>    </code><code>if</code> <code>(keys==nil||keys.count==0) {</code>

<code>        </code><code>[sqlstr appendformat:@</code><code>" * from %@"</code><code>,tablename];</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;keys.count; i++) {</code>

<code>            </code><code>if</code> <code>(i&lt;keys.count-1) {</code>

<code>                </code><code>[sqlstr appendformat:@</code><code>" %@,"</code><code>,keys[i].allkeys.firstobject];</code>

<code>            </code><code>}</code><code>else</code><code>{</code>

<code>                </code><code>[sqlstr appendformat:@</code><code>" %@ from %@"</code><code>,keys[i].allkeys.firstobject,tablename];</code>

<code>            </code> 

<code>    </code><code>if</code> <code>(wlstr) {</code>

<code>    </code><code>if</code> <code>(orderkey) {</code>

<code>        </code><code>[sqlstr appendformat:@</code><code>" order by %@"</code><code>,orderkey];</code>

<code>    </code><code>if</code> <code>(type) {</code>

<code>        </code><code>[sqlstr appendformat:@</code><code>" %@"</code><code>,type];</code>

<code>    </code><code>nsmutablearray * keysarr = [[nsmutablearray alloc]init];</code>

<code>    </code><code>nsmutablearray * keystypearr = [[nsmutablearray alloc]init];</code>

<code>        </code><code>nsarray&lt;nsdictionary *&gt; * tmparr = [self getthetableallkeys:tablename];</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;tmparr.count; i++) {</code>

<code>            </code><code>nsstring * key = tmparr[i].allkeys.firstobject;</code>

<code>            </code><code>[keysarr addobject:key];</code>

<code>            </code><code>[keystypearr addobject:[tmparr[i] objectforkey:key]];</code>

<code>            </code><code>nsstring * key = keys[i].allkeys.firstobject;</code>

<code>            </code><code>[keystypearr addobject:[keys[i] objectforkey:key]];</code>

<code>    </code><code>[self runselectsql:sqlstr withkeys:keysarr withdatatype:keystypearr callback:^(nsarray&lt;nsdictionary *&gt; *dataarray, yhbasesqlerror *error) {</code>

<code>            </code><code>complete(dataarray,error);</code>

<code>   </code> 

<code>-(</code><code>void</code><code>)closecontext{</code>

<code>    </code><code>sqlite3_close(_sqlite3_db);</code>

<code>    </code><code>_sqlite3_db = nil;</code>

<code>//内部方法 運作建立獨立的非查詢sql語句</code>

<code>-(</code><code>void</code><code>)runsql:(nsstring *)sql callback:(</code><code>void</code><code>(^)(yhbasesqlerror * error))complete{</code>

<code>    </code><code>char</code> <code>* err;</code>

<code>    </code><code>int</code> <code>code = sqlite3_exec(_sqlite3_db, [sql utf8string], null, null, &amp;err);</code>

<code>    </code><code>if</code> <code>(code!=sqlite_ok) {</code>

<code>        </code><code>yhbasesqlerror * error = [[yhbasesqlerror alloc]init];</code>

<code>        </code><code>error.errorinfo = [nsstring stringwithcstring:err encoding:nsutf8stringencoding];</code>

<code>        </code><code>error.errorcode = code;</code>

<code>        </code><code>complete(error);</code>

<code>        </code><code>complete(nil);</code>

<code>//運作查詢語句</code>

<code>-(</code><code>void</code><code>)runselectsql:(nsstring *)sql withkeys:(nsarray *)keys withdatatype:(nsarray *)datatype callback:(</code><code>void</code><code>(^)(nsarray&lt;nsdictionary *&gt; * dataarray, yhbasesqlerror * error))complete{</code>

<code>    </code><code>int</code> <code>code = sqlite3_prepare_v2(_sqlite3_db, [sql utf8string], -1, &amp;stmt, null);</code>

<code>        </code><code>error.errorinfo = @</code><code>"查詢失敗"</code><code>;</code>

<code>        </code><code>error.errorcode=code;</code>

<code>        </code><code>complete(nil,error);</code>

<code>        </code><code>nsmutablearray * resultarray = [[nsmutablearray alloc]init];</code>

<code>        </code><code>while</code> <code>(sqlite3_step(stmt)==sqlite_row) {</code>

<code>            </code><code>//資料類型的分别解析</code>

<code>            </code><code>nsmutabledictionary * dic = [[nsmutabledictionary alloc]init];</code>

<code>            </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;datatype.count; i++) {</code>

<code>                </code><code>nsstring * type = datatype[i];</code>

<code>                </code><code>if</code> <code>([type isequaltostring:yhbase_sql_datatype_binary]) {</code>

<code>                    </code><code>int</code> <code>length = sqlite3_column_bytes(stmt, i);</code>

<code>                    </code><code>const</code> <code>void</code> <code>*data = sqlite3_column_blob(stmt, i);</code>

<code>                    </code><code>nsdata * value = [nsdata datawithbytes:data length:length];</code>

<code>                    </code><code>[dic  setobject:value forkey:keys[i]];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_blob]){</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_boolean]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithint:sqlite3_column_int(stmt, i)];</code>

<code>                    </code><code>[dic setobject:value forkey:keys[i]];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_currency]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithlong:sqlite3_column_int64(stmt, i)];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_date]){</code>

<code>                    </code><code>char</code> <code>* cstring =(</code><code>char</code><code>*)sqlite3_column_text(stmt, i);</code>

<code>                    </code><code>nsstring * value = [nsstring stringwithcstring:cstring?cstring:</code><code>"null"</code> <code>encoding:nsutf8stringencoding];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_double]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithfloat:sqlite3_column_double(stmt, i)];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_float]){</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_intrger]){</code>

<code>                    </code> 

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_real]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithdouble:sqlite3_column_int(stmt, i)];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_smallint]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithshort:sqlite3_column_int(stmt, i)];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_text]){</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_time]){</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_timestamp]){</code>

<code>                    </code><code>nsnumber * value = [nsnumber numberwithlonglong:sqlite3_column_int64(stmt, i)];</code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>([type isequaltostring:yhbase_sql_datatype_varchar]){</code>

<code>                </code><code>}</code>

<code>               </code> 

<code>             </code><code>[resultarray addobject:dic];</code>

<code>        </code><code>stmt=nil;</code>

<code>        </code><code>complete(resultarray,nil);</code>

<code>//擷取表中所有字段名和類型</code>

<code>-(nsarray&lt;nsdictionary *&gt; *)getthetableallkeys:(nsstring *)tablename{</code>

<code>    </code><code>nsmutablearray * array = [[nsmutablearray alloc]init];</code>

<code>    </code><code>nsstring * getcolumn = [nsstring stringwithformat:@</code><code>"pragma table_info(%@)"</code><code>,tablename];</code>

<code>    </code><code>sqlite3_stmt *statement;</code>

<code>    </code><code>sqlite3_prepare_v2(_sqlite3_db, [getcolumn utf8string], -1, &amp;statement, nil);</code>

<code>    </code><code>while</code> <code>(sqlite3_step(statement) == sqlite_row) {</code>

<code>        </code><code>char</code> <code>*namedata = (</code><code>char</code> <code>*)sqlite3_column_text(statement, 1);</code>

<code>        </code><code>nsstring *columnname = [[nsstring alloc] initwithutf8string:namedata];</code>

<code>        </code><code>char</code> <code>*typedata = (</code><code>char</code> <code>*)sqlite3_column_text(statement, 2);</code>

<code>        </code><code>nsstring *columntype = [nsstring stringwithcstring:typedata encoding:nsutf8stringencoding];</code>

<code>        </code><code>nsdictionary * dic = @{columnname:columntype};</code>

<code>        </code><code>[array addobject:dic];</code>

<code>     </code><code>sqlite3_finalize(statement);</code>

<code>    </code><code>statement=nil;</code>

<code>    </code><code>return</code> <code>array;</code>

yhbasesqlerror.h

<code> </code><code>*異常的提示資訊</code>

<code>__property_no_strong__(nsstring *, errorinfo);</code>

<code> </code><code>*異常的對應code碼</code>

<code>__property_no_assign__(nsinteger, errorcode);</code>

還有一個頭檔案中定義了sqlite資料庫支援的資料類型和排序宏定義:

yhbasesqltypeheader.h

<code>#define yhbase_sql_datatype_smallint @"smallint" //short</code>

<code>#define yhbase_sql_datatype_intrger @"integer"    //int</code>

<code>#define yhbase_sql_datatype_real @"real"          //實數</code>

<code>#define yhbase_sql_datatype_float @"float"        //float</code>

<code>#define yhbase_sql_datatype_double @"double"      //double</code>

<code>#define yhbase_sql_datatype_currency @"currency"  //long</code>

<code>#define yhbase_sql_datatype_varchar @"varchar"    //char</code>

<code>#define yhbase_sql_datatype_text @"text"          //string</code>

<code>#define yhbase_sql_datatype_binary @"binary"      //二進制</code>

<code>#define yhbase_sql_datatype_blob @"blob"          //長二進制</code>

<code>#define yhbase_sql_datatype_boolean @"boolean"    //bool</code>

<code>#define yhbase_sql_datatype_date @"date"          //日期</code>

<code>#define yhbase_sql_datatype_time @"time"          //時間</code>

<code>#define yhbase_sql_datatype_timestamp @"timestamp"//時間戳</code>

<code>#define yhbase_sql_ordertype_asc @"asc" //升序</code>

<code>#define yhbase_sql_ordertype_desc @"desc" //降序</code>

        在使用時,直接調用context的相應方法操作資料庫即可,例如:

<code>yhbasesqlitecontext * context = [yhbasesqlitemanager opensqlitewithname:@</code><code>"testdatabase"</code><code>];</code>

<code>    </code><code>if</code> <code>(context) {</code>

<code>        </code><code>[context selectkeys:nil fromtable:@</code><code>"mysql"</code> <code>orderby:@</code><code>"age"</code> <code>ordertype:yhbase_sql_ordertype_desc whilestr:@</code><code>"age&gt;18"</code> <code>callback:^(nsarray&lt;nsdictionary *&gt; *dataarray, yhbasesqlerror *error) {</code>

<code>            </code><code>nslog(@</code><code>"%@"</code><code>,dataarray);</code>

<code>            </code><code>nslog(@</code><code>"%@"</code><code>,error.errorinfo);</code>

<code>            </code><code>[context closecontext];</code>

<code>        </code><code>}];</code>

上面的代碼将查詢textdatabase資料庫中mysql表裡所有age列大于18的資料,并按照age從小到大進行排序,資料結果在回調的dataarray中。