iOS开发:用SQLite3存储和读取数据

移动开发 iOS
SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。

SQLite3是嵌入在iOS中的关系型数据库,对于存储大规模的数据很有效。SQLite3使得不必将每个对象都加到内存中。

基本操作:

(1)打开或者创建数据库

  1. sqlite3 *database; 
  2. int result = sqlite3_open("/path/databaseFile", &database); 

如果/path/databaseFile不存在,则创建它,否则打开它。如果result的值是SQLITE_OK,则表明我们的操作成功。

注意上述语句中数据库文件的地址字符串前面没有@字符,它是一个C字符串。将NSString字符串转成C字符串的方法是:

  1. const char *cString = [nsString UTF8String]; 

(2)关闭数据库

  1. sqlite3_close(database); 

(3)创建一个表格

  1. char *errorMsg; 
  2. const char *createSQL = "CREATE TABLE IF NOT EXISTS PEOPLE (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_DATA TEXT)"
  3. int result = sqlite3_exec(database, createSQL, NULL, NULL, &errorMsg); 

执行之后,如果result的值是SQLITE_OK,则表明执行成功;否则,错误信息存储在errorMsg中。

sqlite3_exec这个方法可以执行那些没有返回结果的操作,例如创建、插入、删除等。

(4)查询操作

  1. NSString *query = @"SELECT ID, FIELD_DATA FROM FIELDS ORDER BY ROW"
  2. sqlite3_stmt *statement; 
  3. int result = sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil); 

如果result的值是SQLITE_OK,则表明准备好statement,接下来执行查询:

  1. while (sqlite3_step(statement) == SQLITE_ROW) { 
  2.     int rowNum = sqlite3_column_int(statement, 0); 
  3.     char *rowData = (char *)sqlite3_column_text(statement, 1); 
  4.     NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData]; 
  5.     // Do something with the data here 
  6. sqlite3_finalize(statement); 

使用过其他数据库的话应该很好理解这段语句,这个就是依次将每行的数据存在statement中,然后根据每行的字段取出数据。

(5)使用约束变量

实际操作时经常使用叫做约束变量的东西来构造SQL字符串,从而进行插入、查询或者删除等。

例如,要执行带两个约束变量的插入操作,***个变量是int类型,第二个是C字符串:

  1. char *sql = "insert into oneTable values (?, ?);"
  2. sqlite3_stmt *stmt; 
  3. if (sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK) { 
  4.     sqlite3_bind_int(stmt, 1, 235); 
  5.     sqlite3_bind_text(stmt, 2, "valueString", -1, NULL); 
  6. if (sqlite3_step(stmt) != SQLITE_DONE) 
  7.     NSLog(@"Something is Wrong!"); 
  8. sqlite3_finalize(stmt); 

这里,sqlite3_bind_int(stmt, 1, 235);有三个参数:

***个是sqlite3_stmt类型的变量,在之前的sqlite3_prepare_v2中使用的。

第二个是所约束变量的标签index。

第三个参数是要加的值。

有一些函数多出两个变量,例如

  1. sqlite3_bind_text(stmt, 2, "valueString", -1, NULL); 

这句,第四个参数代表第三个参数中需要传递的长度。对于C字符串来说,-1表示传递全部字符串。

第五个参数是一个回调函数,比如执行后做内存清除工作。

接下来,做个小例子吧!

1、运行Xcode 4.3,新建一个Single View Application,名称为SQLite3 Test:

2、连接SQLite3库:

按照下图中的红色数字的顺序找到加号:

单击这个加号,打开窗口,在搜索栏输入sqlite3:

选择libsqlite3.dylib,单击Add,添加到工程。

3、进行界面设计。打开ViewController.xib,使用Interface Builder设计界面如下:

设置四个文本框的tag分别是1、2、3、4。

4、在ViewController.h中添加属性和方法:

  1. @property (copy, nonatomic) NSString *databaseFilePath; 
  2.  
  3. - (void)applicationWillResignActive:(NSNotification *)notification; 

5、打开ViewController.m,向其中添加代码:

5.1 在开头添加代码:

  1. #import "sqlite3.h" 
  2. #define kDatabaseName @"database.sqlite3" 

5.2 在@implementation之后添加代码:

  1. @synthesize databaseFilePath; 

5.3 在viewDidLoad方法中添加代码:

  1. - (void)viewDidLoad 
  2.     [super viewDidLoad]; 
  3.     // Do any additional setup after loading the view, typically from a nib. 
  4.     //获取数据库文件路径 
  5.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
  6.     NSString *documentsDirectory = [paths objectAtIndex:0]; 
  7.     self.databaseFilePath = [documentsDirectory stringByAppendingPathComponent:kDatabaseName]; 
  8.     //打开或创建数据库 
  9.     sqlite3 *database; 
  10.     if (sqlite3_open([self.databaseFilePath UTF8String] , &database) != SQLITE_OK) { 
  11.         sqlite3_close(database); 
  12.         NSAssert(0, @"打开数据库失败!"); 
  13.     } 
  14.     //创建数据库表 
  15.     NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS (TAG INTEGER PRIMARY KEY, FIELD_DATA TEXT);"
  16.     char *errorMsg; 
  17.     if (sqlite3_exec(database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) { 
  18.         sqlite3_close(database); 
  19.         NSAssert(0, @"创建数据库表错误: %s", errorMsg); 
  20.     } 
  21.     //执行查询 
  22.     NSString *query = @"SELECT TAG, FIELD_DATA FROM FIELDS ORDER BY TAG"
  23.     sqlite3_stmt *statement; 
  24.     if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) { 
  25.         //依次读取数据库表格FIELDS中每行的内容,并显示在对应的TextField 
  26.         while (sqlite3_step(statement) == SQLITE_ROW) { 
  27.             //获得数据 
  28.             int tag = sqlite3_column_int(statement, 0); 
  29.             char *rowData = (char *)sqlite3_column_text(statement, 1); 
  30.             //根据tag获得TextField 
  31.             UITextField *textField = (UITextField *)[self.view viewWithTag:tag]; 
  32.             //设置文本 
  33.             textField.text = [[NSString alloc] initWithUTF8String:rowData]; 
  34.         } 
  35.         sqlite3_finalize(statement); 
  36.     } 
  37.     //关闭数据库 
  38.     sqlite3_close(database); 
  39.     //当程序进入后台时执行写入数据库操作 
  40.     UIApplication *app = [UIApplication sharedApplication]; 
  41.     [[NSNotificationCenter defaultCenter] 
  42.      addObserver:self 
  43.      selector:@selector(applicationWillResignActive:) 
  44.      name:UIApplicationWillResignActiveNotification 
  45.      object:app]; 

5.4 在@end之前实现方法:

  1. //程序进入后台时的操作,实现将当前显示的数据写入数据库 
  2. - (void)applicationWillResignActive:(NSNotification *)notification { 
  3.     //打开数据库 
  4.     sqlite3 *database; 
  5.     if (sqlite3_open([self.databaseFilePath UTF8String], &database) 
  6.         != SQLITE_OK) { 
  7.         sqlite3_close(database); 
  8.         NSAssert(0, @"打开数据库失败!"); 
  9.     } 
  10.     //向表格插入四行数据 
  11.     for (int i = 1; i <= 4; i++) {  
  12.         //根据tag获得TextField 
  13.         UITextField *textField = (UITextField *)[self.view viewWithTag:i]; 
  14.         //使用约束变量插入数据 
  15.         char *update = "INSERT OR REPLACE INTO FIELDS (TAG, FIELD_DATA) VALUES (?, ?);"
  16.         sqlite3_stmt *stmt; 
  17.         if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) { 
  18.             sqlite3_bind_int(stmt, 1, i); 
  19.             sqlite3_bind_text(stmt, 2, [textField.text UTF8String], -1, NULL); 
  20.         } 
  21.         char *errorMsg = NULL; 
  22.         if (sqlite3_step(stmt) != SQLITE_DONE) 
  23.             NSAssert(0, @"更新数据库表FIELDS出错: %s", errorMsg); 
  24.         sqlite3_finalize(stmt); 
  25.     } 
  26.     //关闭数据库 
  27.     sqlite3_close(database); 

6、实现关闭键盘,参考《iOS开发4:关闭键盘》中的第2步。其中,backgroundTap方法如下:

  1. //关闭键盘 
  2. - (IBAction)backgroundTap:(id)sender { 
  3.     for (int i = 1; i <= 4; i++) { 
  4.         UITextField *textField = (UITextField *)[self.view viewWithTag:i]; 
  5.         [textField resignFirstResponder]; 
  6.     } 

7、运行程序:

刚运行时显示如下面左图:

在各个文本框输入内容,如上面右图。然后按Home键,这样,就执行了写入数据的操作。

***次运行程序时,在SandBox的Documents目录下出现数据库文件database.sqlite3:

此时退出程序,再次运行,则显示的就是上次退出时的值。

责任编辑:闫佳明 来源: cocoachina
相关推荐

2012-03-06 12:59:11

iOS SQLite3iOSSQLite3

2012-03-06 10:17:45

iOS SQLite3iOSSQLite3

2021-02-15 15:40:28

SQLite3数据库

2011-07-07 16:42:38

iPhone Sqlite3 数据库

2013-04-10 14:21:35

2013-04-09 16:47:19

iOS嵌入式数据库SQLit

2012-02-29 10:18:31

SQLite3Android

2019-08-12 11:40:48

数据库SQLite3数据类型

2011-08-15 17:20:25

iPhone应用Sqlite3FMDB

2012-03-01 20:42:12

iPhone

2011-08-05 16:50:00

iPhone 数据 Sqlite

2017-10-26 12:37:24

Pythonsqlite3数据库

2012-03-06 09:50:24

Android SQLAndroidSQLite3

2011-08-01 13:32:07

Objective-C Sqlite3 框架

2011-07-05 17:38:52

QT Sqlite

2013-04-01 10:49:51

iOS开发sqlite数据库

2024-02-19 00:00:00

SQLite3数据库代码

2011-09-07 15:39:08

iPhoneObjective-CSQLite3

2020-09-24 16:05:44

C语言sqlite3函数

2017-09-17 12:21:52

移植Linux系统sqlite3
点赞
收藏

51CTO技术栈公众号