原文:http://hi.baidu.com/clickto/blog/item/0c6904f787c34125720eec87.html

iPhone中支持通过sqlite3来访问iPhone本地的数据库。

具体使用方法如下

1:添加开发包libsqlite3.0.dylib

首先是设置项目文件,在项目中添加iPhone版的sqlite3的数据库的开发包,在项目下的Frameworks点击右键,然后选择libsqlite3.0.dylib文件。

libsqlite3.0.dylib文件地址: 
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk/usr/lib/libsqlite3.0.dylib

2,代码中的操作:

那么接下来是代码了。

1 首先获取iPhone上sqlite3的数据库文件的地址

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database_name"];

打开iPhone上的sqlite3的数据库文件

sqlite3 *database;
sqlite3_open([path UTF8String], &database);

3 准备sql文---sql语句

sqlite3_stmt *stmt;
const char *sql = "SELECT * FROM table_name WHERE pk=? and name=?";
sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);

邦定参数

// 邦定第一个int参数
sqlite3_bind_int(stmt, 1, 1);
// 邦定第二个字符串参数
sqlite3_bind_text(stmt, 2, [title UTF8String], -1, SQLITE_TRANSIENT);

执行sql文

sqlite3_step(stmt);

释放sql文资源

sqlite3_finalize(stmt);

关闭iPhone上的sqlite3的数据库

sqlite3_close(database);

以下演示一下使用sqlite的步骤,先创建一个数据库,然后查询其中的内容。2个重要结构体和5个主要函数:

sqlite3               *pdb, 数据库句柄,跟文件句柄FILE很类似

sqlite3_stmt      *stmt, 这个相当于ODBC的Command对象,用于保存编译好的SQL语句

sqlite3_open(),   打开数据库

sqlite3_exec(),   执行非查询的sql语句

sqlite3_prepare(), 准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_exec).

Sqlite3_step(), 在调用sqlite3_prepare后,使用这个函数在记录集中移动。

Sqlite3_close(), 关闭数据库文件

还有一系列的函数,用于从记录集字段中获取数据,如

sqlite3_column_text(), 取text类型的数据。

sqlite3_column_blob(),取blob类型的数据

sqlite3_column_int(), 取int类型的数据

PreparedStatement方式处理SQL请求的过程
特点:可以绑定参数,生成过程。执行的时候像是ADO一样,每次返回一行结果。

1. 首先建立statement对象:
int sqlite3_prepare(
sqlite3 *db,            /* Database handle */
const char *zSql,       /* SQL statement, UTF-8 encoded */
int nBytes,             /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

2. 绑定过程中的参数(如果有没有确定的参数)
int sqlite3_bind_xxxx(sqlite3_stmt*, int, ...);
第二个int类型参数-表示参数的在SQL中的序号(从1开始)。
第三个参数为要绑定参数的值。
对于blob和text数值的额外参数:
第四参数是字符串(Unicode 8or16)的长度,不包括结束'\0'。
第五个参数,类型为void(*)(void*),表示SQLite处理结束后用于清理参数字符串的函数。
没有进行绑定的未知参数将被认为是NULL。

3. 执行过程
int sqlite3_step(sqlite3_stmt*);
可能的返回值:
*SQLITE_BUSY:   数据库被锁定,需要等待再次尝试直到成功。
*SQLITE_DONE:   成功执行过程(需要再次执行一遍以恢复数据库状态)
*SQLITE_ROW:    返回一行结果(使用sqlite3_column_xxx(sqlite3_stmt*,, int iCol)得到每一列的结果。
再次调用将返回下一行的结果。
*SQLITE_ERROR:  运行错误,过程无法再次调用(错误内容参考sqlite3_errmsg函数返回值)
*SQLITE_MISUSE: 错误的使用了本函数(一般是过程没有正确的初始化)

4. 结束的时候清理statement对象
int sqlite3_finalize(sqlite3_stmt *pStmt);
应该在关闭数据库之前清理过程中占用的资源。

5. 重置过程的执行 
int sqlite3_reset(sqlite3_stmt *pStmt);
过程将回到没有执行之前的状态,绑定的参数不会变化。

例子:
创建数据库

  1. NSString *docsDir;
  2. NSArray *dirPaths;
  3. dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  4. docsDir = [dirPaths objectAtIndex:0];
  5. databasePath = [[NSString alloc]initWithString:[docsDir stringByAppendingPathComponent:@"info.db"]];
  6. NSFileManager *fileManager = [NSFileManager defaultManager];
  7. if ([fileManager fileExistsAtPath:databasePath]==NO) {
  8. const charchar *dbpath = [databasePath UTF8String];
  9. if (sqlite3_open(dbpath, &dataBase)==SQLITE_OK) {
  10. charchar *errmsg;
  11. const charchar *createSql = "CREATE TABLE IF NOT EXISTS INFO (ID INTEGER PRIMARY KEY AUTOINCREMENT,NUM TEXT,CLASSNAME TEXT,NAME TEXT)";
  12. if (sqlite3_exec(dataBase, createSql, NULL, NULL, &errmsg)!=SQLITE_OK) {
  13. status.text = @"create table failed";
  14. }
  15. }
  16. else{
  17. status.text = @"create/open failled";
  18. }
  19. }

保存

  1. sqlite3_stmt *statement;
  2. const charchar *dbpath = [databasePath UTF8String];
  3. if (sqlite3_open(dbpath, &dataBase)==SQLITE_OK) {
  4. if ([num.text isEqualToString:@""]) {
  5. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"SORRY!" message:@"number cannot be nil!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
  6. [alert show];
  7. }
  8. else {
  9. NSString *insertSql = [NSString stringWithFormat:@"INSERT INTO INFO (num,classname,name) VALUES(\"%@\",\"%@\",\"%@\")",num.text,classname.text,name.text];
  10. const charchar *insertsatement = [insertSql UTF8String];
  11. sqlite3_prepare_v2(dataBase, insertsatement, -1, &statement, NULL);
  12. if (sqlite3_step(statement)==SQLITE_DONE) {
  13. status.text = @"save to DB.";
  14. num.text = @"";
  15. classname.text = @"";
  16. name.text = @"";
  17. }
  18. else {
  19. status.text = @"save failed!";
  20. }
  21. sqlite3_finalize(statement);
  22. sqlite3_close(dataBase);
  23. }
  24. }

清除:

  1. num.text = @"";
  2. classname.text = @"";
  3. name.text = @"";
  4. status.text = @"";
  1. <span style="font-size:24px;"><strong><span style="color:#ff00;">查询:</span></strong></span>
    1. <pre code_snippet_id="310162" snippet_file_name="blog_20140424_5_1884255" class="objc" name="code">const charchar *dbpath = [databasePath UTF8String];
    2. sqlite3_stmt *statement;
    3. if (sqlite3_open(dbpath, &dataBase)==SQLITE_OK) {
    4. NSString *querySQL = [NSString stringWithFormat:@"SELECT classname,name from info where num=\"%@\"",num.text];
    5. const charchar *querystatement = [querySQL UTF8String];
    6. if (sqlite3_prepare_v2(dataBase, querystatement, -1, &statement, NULL)==SQLITE_OK) {
    7. if (sqlite3_step(statement)==SQLITE_ROW) {
    8. NSString *classnameField = [[NSString alloc] initWithUTF8String:(const charchar *)sqlite3_column_text(statement, 0)];
    9. classname.text = classnameField;
    10. NSString *nameField = [[NSString alloc] initWithUTF8String:(const charchar *) sqlite3_column_text(statement, 1)];
    11. name.text = nameField;
    12. status.text = @"find~~~";
    13. }
    14. else {
    15. status.text = @"did not find you need.";
    16. }
    17. sqlite3_finalize(statement);
    18. }
    19. sqlite3_close(dataBase);
    20. }</pre><br>
    21. 其他工具函数<br>
    22. 1. 得到结果总共的行数<br>
    23. int sqlite3_column_count(sqlite3_stmt *pStmt);<br>
    24. 如果过程没有返回值,如update,将返回0<br>
    25. <br>
    26. 2. 得到当前行中包含的数据个数<br>
    27. int sqlite3_data_count(sqlite3_stmt *pStmt);<br>
    28. 如果sqlite3_step返回SQLITE_ROW,可以得到列数,否则为零。<br>
    29. <br>
    30. 3. 得到数据行中某个列的数据<br>
    31. sqlite3_column_xxx(sqlite3_stmt*, int iCol);<br>
    32. 在sqlite3_step返回SQLITE_ROW后,使用它得到第iCol列的数据。<br>
    33. 其中的xxx代表:<br>
    34. blob:指向保存数据内存的指针<br>
    35. bytes, bytes16: 得到该blob类型数据的大小,或者text转换为UTF8/UTF16的字符串长度。<br>
    36. double, int, int64: 数值<br>
    37. text,text16:字符串指针<br>
    38. type:该列的数据类型(SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL)<br>
    39. 注意:如果对该列使用了不同与该列本身类型适合的数据读取方法,得到的数值将是转换过的结果。<br>
    40. <br>
    41. 4. 得到数据行中某个列的数据的类型<br>
    42. int sqlite3_column_type(sqlite3_stmt*, int iCol);<br>
    43. 返回值:SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL<br>
    44. 使用的方法和sqlite3_column_xxx()函数类似。<br>
    45. <br>
    46. //////////////////////////////////////Sqlite 資料庫檔案的產生<br>
    47. MAC 上有許多應用程式都可以用來產生它,有 UI 界面很方便。但如果不想另外安裝軟體,MAC 系統也內建 sqlite3 的元件,可由 console 來建立。首先我們先開啟任何一款文書編輯軟體,以 sql 語法來手動建立,並存成 data.sql。<br>
    48. <br>
    49. <div>
    50. <div>
    51. <div>1BEGINTRANSACTION;</div>
    52. <div>2CREATETABLE'Info'(_id INTEGERPRIMARYKEY, 'Name'TEXT, 'Tel'TEXT, 'Address'TEXT);</div>
    53. <div>3INSERTINTO'Info'VALUES(1,'Richie','1234567','台中市');</div>
    54. <div>4INSERTINTO'Info'VALUES(2,'Eric','7654321','台北市');</div>
    55. <div>5INSERTINTO'Info'VALUES(3,'Andy','1234321','高雄市');</div>
    56. <div>6COMMIT;</div>
    57. </div>
    58. </div>
    59. <br>
    60. <br>
    61. 然後在 console 下達以下指令 來產生 data.rdb 這個 sqlite file<br>
    62. <br>
    63. <div>
    64. <div>
    65. <div>1sqlite3 data.rdb < data.sql</div>
    66. </div>
    67. </div>
    68. <br>
    69. <br>
    70. iOS 專案使用 Sqlite 資料庫<br>
    71. 先將剛才產生的資料庫加入專案中,然後在專案中加入 libsqlite3.0.dylib。<br>
    72. <br>
    73. <br>
    74. <br>
    75. 接下來開始撰寫程式碼了,xxxAppDelegate.h 必須 import sqlite3.h,並宣告一個 sqlite3 結構。<br>
    76. <pre code_snippet_id="310162" snippet_file_name="blog_20140424_6_8754335" class="objc" name="code">#import "sqlite3.h"
    77. @interfacexxxAppDelegate : NSObject<UIApplicationDelegate>
    78. {
    79. sqlite3* database;
    80. }
    81. 在 xxxAppDelegate.m 的 didFinishLaunchingWithOptions 函式 開始加入相關程式碼
    82. - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    83. {
    84. // 檢查資料庫是否存在,不存在時則 copy
    85. NSString*path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    86. NSString*file = [path stringByAppendingPathComponent:@"data.rdb"];
    87. if([[NSFileManagerdefaultManager] fileExistsAtPath:file] == FALSE)
    88. {
    89. NSString*fromFile = [[NSBundlemainBundle] pathForResource:@"data.rdb"ofType:nil];
    90. [[NSFileManagerdefaultManager] copyItemAtPath:fromFile toPath:file error:nil];
    91. }
    92. // open
    93. if(sqlite3_open([file UTF8String], &database) != SQLITE_OK)
    94. NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
    95. self.window.rootViewController = self.viewController;
    96. [self.window makeKeyAndVisible];
    97. returnYES;
    98. }
    99. - (void)dealloc
    100. {
    101. sqlite3_close(database);
    102. [superdealloc];
    103. }</pre><br>
    104. 簡 單說明一下,將 data.rdb 加入專案中後,該資料庫會出現在 app 套件內,但每個 app 就只有專屬 Documents 目錄可以讀寫。所以必須判斷 Documents 目錄下該檔案是否存在,如果不存在則 copy 過去該目錄後再 open 資料庫。至於為什麼做判斷?為什麼不每次都 copy 過去即可?因為如果不希望該資料庫在每次 app 版本更新後,都會被覆蓋掉,就得做檔案存在與否的判斷。<br>
    105. <br>
    106. 讀取資料庫<br>
    107. 有成功 open 資料庫之後,就可以開始進行讀寫了。讀取資料庫的方法,其實也是很簡單,只要熟悉 SQL 語法,應該就沒什麼問題了。<br>
    108. <pre code_snippet_id="310162" snippet_file_name="blog_20140424_7_4960107" class="objc" name="code">NSString*sql = [NSStringstringWithFormat:@"SELECT * FROM Event "];
    109. sqlite3_stmt *statement;
    110. if(sqlite3_prepare_v2(database, 1, -1, &statement, NULL) == SQLITE_OK)
    111. {
    112. while (sqlite3_step(statement) == SQLITE_ROW)
    113. {
    114. NSString*strValue = [NSStringstringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
    115. intintValue = sqlite3_column_int(statement, 1);
    116. }
    117. }
    118. sqlite3_finalize(statement);</pre><br>
    119. 其中必須注意的是 sqlite3_column_text, sqlite3_column_int 負責取得資料,必須指定是哪個 column index。<br>
    120. <br>
    121. 執行 SQL 命令<br>
    122. 上述是 SELECT 的用法,但是如果需要做 INSERT, DELETE, UPDATE 等動作時,則更是簡單,只需以下指令即可。<br>
    123. <pre code_snippet_id="310162" snippet_file_name="blog_20140424_8_3433372" class="objc" name="code">char*errMsg;
    124. NSString*sql = [NSStringstringWithFormat:@"CREATE TABLE 'Info' (_id INTEGER PRIMARY KEY, 'Name' TEXT, 'Tel' TEXT, 'Address' TEXT)"];
    125. sqlite3_exec(database, 1, nil, nil, &errMsg);</pre><br>
    126. <pre></pre>

iOS关于sqlite3操作的更多相关文章

  1. iOS中sqlite3操作

    声明:下面命令我没有所有使用过, 仅用于收藏, 欢迎大家指出当中的错误 'SELECT  count(*)   FROM sqlite_master WHERE type="table&qu ...

  2. ios在SQLite3基本操作

    iOS关于sqlite3操作 iPhone中支持通过sqlite3来訪问iPhone本地的数据库. 详细用法例如以下 1:加入开发包libsqlite3.0.dylib 首先是设置项目文件.在项目中加 ...

  3. 使用iOS原生sqlite3框架对sqlite数据库进行操作

    摘要: iOS中sqlite3框架可以很好的对sqlite数据库进行支持,通过面向对象的封装,可以更易于开发者使用. 使用iOS原生sqlite3框架对sqlite数据库进行操作 一.引言 sqlit ...

  4. ios对SQLite3的使用

    ios对SQLite3的使用 一.在Firefox中打开sqlite3(如果没有,选择工具->附加组件,添加即可)新建sqlite3数据库,Contacts, 建立一个members表,字段 i ...

  5. iOS - SQLite Database 操作数据库

    iOS - SQLite Database 操作数据库   Sqlite 能被用在ios上做数据处理用,只要你懂得一点sql 就很容易使用sqlite 1:创建一个简单的View based appl ...

  6. iOS多线程拾贝------操作巨人编程

    iOS多线程拾贝------操作巨人编程 多线程 基本 实现方案:pthread - NSThread - GCD - NSOperation Pthread 多平台,可移植 c语言,要程序员管理生命 ...

  7. IOS各种手势操作实例

    先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击  UITapGestureRecogniz ...

  8. iOS子线程操作检测版本更新,有新版本通知用户更新, CheckVersion

    iOS子线程操作检测版本更新,有新版本通知用户更新 CheckVersion 一:如何使用: #import "CheckVersion.h" //输入你的app在appStore ...

  9. iOS 本地通知 操作

    iOS 本地通知 操作 1:配置通知:然后退出程序: UILocalNotification *localNotif = [[UILocalNotification alloc] init]; loc ...

随机推荐

  1. Artem and Array

    Codeforces Round #253 (Div. 1) C:http://codeforces.com/problemset/problem/442/C 题意:给你一个序列,然后你每次可以删除一 ...

  2. Children of the Candy Corn

    poj3083:http://poj.org/problem?id=3083 题意:给你一个迷宫,然后给你一个起点和终点,现在给你种规则,一种是先向左,无法向左则向前,无法向前则向右,否则则向后,另外 ...

  3. Zabbix的集中式监控

    相对于传统的ZABBIX硬件系统级监控(CPU,内存,硬盘,网卡),应用级的监控就显得有些复杂了. 如果对不同的应该来不同的应用,配置会很多的. 如果我们能在一个指定的AGENT上监控所有的APACH ...

  4. IIC协议及其对ACK应答信号的处理

    1,SCL一直由Master控制,SDA依照数据传送的方向,读数据时由Slave控制SDA,写数据时由Master控制SDA.当8位数据传送完毕之后,应答位或者否应答位的SDA控制权与数据位传送时相反 ...

  5. Timus1132(二次剩余方程求解)

    题目:http://acm.timus.ru/problem.aspx?space=1&num=1132 题意:就是给出方程,p为素数,求在区间内的解. 这个思路很简单,详见:http://a ...

  6. HDU 5410 CRB and His Birthday

    题目大意: 一个人要去买礼物,有M元.有N种礼物,每件礼物的价值是Wi, 你第i件礼物买k个 是可以得到 Ai * k + Bi 个糖果的. 问怎么才能使得你得到的糖果数目最多.   其实就是完全背包 ...

  7. Linux下的定时器:alarm()与setitimer()

    Linux下的定时器有两种,以下分别介绍: 1.alarm 如果不要求很精确的话,用alarm()和signal()就够了 unsigned int alarm(unsigned int second ...

  8. First Bad Version——LeetCode

    You are a product manager and currently leading a team to develop a new product. Unfortunately, the ...

  9. Book for Opencv

    Upcoming: Learning OpenCV: Computer Vision in C++ with the OpenCV Library The second edition of the ...

  10. 数据结构——foodfill 八连块问题

    Description Due to recent rains, water has pooled in various places in Farmer John's field, which is ...