转自:http://my.oschina.net/plumsoft/blog/57626

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

基本操作:

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

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

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

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

const char *cString = [nsString UTF8String];

(2)关闭数据库

sqlite3_close(database);

(3)创建一个表格

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

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

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

(4)查询操作

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

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

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

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

(5)使用约束变量

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

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

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

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

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

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

第三个参数是要加的值。

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

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中添加属性和方法:

@property (copy, nonatomic) NSString *databaseFilePath;

- (void)applicationWillResignActive:(NSNotification *)notification;

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

5.1 在开头添加代码:

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

5.2 在@implementation之后添加代码:

@synthesize databaseFilePath;

5.3 在viewDidLoad方法中添加代码:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//获取数据库文件路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
self.databaseFilePath = [documentsDirectory stringByAppendingPathComponent:kDatabaseName];
//打开或创建数据库
sqlite3 *database;
if (sqlite3_open([self.databaseFilePath UTF8String] , &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, @"打开数据库失败!");
}
//创建数据库表
NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS (TAG INTEGER PRIMARY KEY, FIELD_DATA TEXT);";
char *errorMsg;
if (sqlite3_exec(database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(0, @"创建数据库表错误: %s", errorMsg);
}
//执行查询
NSString *query = @"SELECT TAG, FIELD_DATA FROM FIELDS ORDER BY TAG";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
//依次读取数据库表格FIELDS中每行的内容,并显示在对应的TextField
while (sqlite3_step(statement) == SQLITE_ROW) {
//获得数据
int tag = sqlite3_column_int(statement, 0);
char *rowData = (char *)sqlite3_column_text(statement, 1);
//根据tag获得TextField
UITextField *textField = (UITextField *)[self.view viewWithTag:tag];
//设置文本
textField.text = [[NSString alloc] initWithUTF8String:rowData];
}
sqlite3_finalize(statement);
}
//关闭数据库
sqlite3_close(database);
//当程序进入后台时执行写入数据库操作
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:app];
}

5.4 在@end之前实现方法:

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

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

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

7、运行程序:

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

   

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

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

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

【转】iOS开发24:使用SQLite3存储和读取数据的更多相关文章

  1. iOS开发中视图控制器ViewControllers之间的数据传递

    iOS开发中视图控制器ViewControllers之间的数据传递 这里我们用一个demo来说明ios是如何在视图控制器之间传递重要的参数的.本文先从手写UI来讨论,在下一篇文章中讨论在storybo ...

  2. iOS开发系列-常见离线存储方式

    概述 在很多社交App手机在手机没有网络时,重新启动应用,依然能否展示上次访问的数据,提高用户体验,这个就是离线数据存储的运用场景.在iOS开发中常见的离线存储技术有Plist存储.个人偏好存储.解归 ...

  3. IOS开发-封装数据库sqlite3之为何选择FMDB

    为什么使用第三方轻量级框架FMDB? FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语 ...

  4. IOS开发-本地持久化存储sqlite应用

    前言 需求描述 开发测试环境 FMDB介绍 创建工程 一.前言 上一章介绍了如何开发一个IOS应用的入门案例教程:                     我的第一个IOS开发应用    本章主要将介 ...

  5. [MISS静IOS开发原创文摘]-AppDelegate存储全局变量和 NSUserDefaults standardUserDefaults 通过模型保存和读取数据,存储自定义的对象

    由于app开发的需求,需要从api接口获得json格式数据并保存临时的 app的主题颜色 和 相关url 方案有很多种: 1, 通过AppDelegate保存为全局变量,再获取 2,使用NSUSerD ...

  6. iOS开发——网络Swift篇&JSON与XML数据解析

    JSON与XML数据解析 JSON数据解析(内置NSJSONSerialization与第三方JSONKit)   一,使用自带的NSJSONSerialization 苹果从IOS5.0后推出了SD ...

  7. iOS NSMutableDictionary中UIImage的存储和读取

    思路:将UIImage转换成NSData,然后插入到NSMutableDictionary中.读取时,用NSData读出来,然后再转换成UIImage -存储 UIImage *image = [se ...

  8. iOS开发NSFetchedResultsController的使用CoreData和TableView数据同步更新

    1.效果 2.代码 #import "ViewController.h" #import "Student+CoreDataProperties.h" #def ...

  9. iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件

    NSURLSession加载数据.下载.上传文件   NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍.   1,使用Data Task加载数据 使用全局的 ...

随机推荐

  1. 配置squid代理服务

    1. 简述一下squid的用途?squid可以做代理和缓存服务器,而做代理时,可以分为正向代理和反向代理.正向代理用在企业办公环境中,企业员工上网通过代理来上网,代理的缓存功能可以为企业节省宝贵的带宽 ...

  2. DataGrid( 数据表格) 组件[1]

    本节课重点了解 EasyUI 中 DataGrid(数据表格)组件的使用方法,这个组件依赖于Panel(面板).Resizeable(调整大小).LinkButton(按钮).Pageination( ...

  3. Neral的前言

    大家好,我是Neral,我准备写一个js库. 在动笔之前,我一直都处在很忐忑的状态,因为我写代码讲究的是一种感觉,那是看到自己写的代码之后大脑中就出现之后的无数个编码分支的快感,但是,如果很长一段时间 ...

  4. JQ简单图片轮播

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. java基础学习----String

    旨在从内存方面看String类的知识点: 1.为何不能被继承(final类) 2.字符拼接时,String类的内存分配问题. 3.String的intern()方法 关于String类经常出现的面试题 ...

  6. C++ Primer 5th 第6章 函数

    正如第一章所说:C++的函数是一个能够完成一个功能的模块或者说是一段命名了的代码块. 如下图所示,函数可以重载,是一段实现某些功能命名了的代码. 一个完整的函数的构成有四部分: 1.返回类型 2.函数 ...

  7. php开发客服系统(持久连接+轮询+反向ajax)

    欢迎在php严程序 - php教程学习AJAX教程, 本节课讲解:php开发客服系统(持久连接+轮询+反向ajax) php开发客服系统(下载源码) 用户端(可直接给客户发送消息)客服端(点击用户名. ...

  8. JavaScript键盘事件全面控制代码

    JavaScript键盘事件全面控制,它可以捕获键盘事件的输入状态,可以判断你敲打了键盘的那个键,ctrl.shift,26个字母等等,返回具体键盘值. <html> <head&g ...

  9. frame嵌套的学习

    iframe嵌套的学习 具体代码<br /> window.onload=function(){<br /> var voteid=window.parent.parent.d ...

  10. 《javascript权威指南》第9章 例9-8源码

    //创建一个新的枚举类型 //不能使用它来创建该类型的新实例 function Enumeration(nameToValues){ var Enumeration = function(){thro ...