iOS应用中,有时需要存储大量的数据,如果使用plist文件存储,这些数据都会存放在内存中,导致内存大量占用,严重影响程序性能。所以,iOS提供了一个轻量级的数据库SQLite,它是一个嵌入式的数据库,专门用于在资源有限的设备上进行数据的适量存储。
SQLite是一款开源的嵌入式关系型数据库,虽然是轻量级的但是在存储和检索大量数据方面非常有效,与使用对象存储数据相比,SQLite数据库获取结果的方式更快。它运行时与使用它的应用程序共享相同的进程空间,而不是单独的两个进程。
在iOS中,数据库和本地应用程序都是存放在MainBundle中或沙盒中的。
在SQLite数据库中,一个数据库是由一张或多张表组成的,每张数据表主要由row和column组成,用于记录某一类信息的完整记录。
数据表中的每一行(row)表示一条记录,每一列表示一个字段。在SQLite中,字段的本质是不区分数据类型的,但是为了编码规范,在定义数据结构的时候一定要指明字段的数据类型,SQLite将字段数据类型分为5种:
数据类型: 描述:
NULL 表示该值为NULL值
INTEGER 无符号整型值
REAL 浮点值
TEXT 文本字符串
BLOB 二进制数据
下面列举一下常用的SQL语句:
1,创建表
创建表的基本格式1:
CREATE TABLE 表名(字段名1 字段类型1,字段名2 字段类型2,...);
创建表的基本格式2:
CREATE TABLE IF NOT EXISTS 表名(字段名1 字段类型1,字段名2 字段类型2,...);
格式2判断创建的表是否存在,如果不存在新表才会创建,这样就不会对原表中的数据进行覆盖。需要注意的是,在对数据库命名时,要避免和关键字命名冲突。
2,删除表
删除表的基本格式1:
DROP TABLE 表名;
删除表的基本格式2:
DROP TABLE IF EXISTS 表名;
3,像表中插入数据
插入数据基本格式:
insert into 表名(字段1,字段2,...) values (字段1的值,字段2的值,...);
4,更新数据
修改数据的基本格式:
update 表名 set 字段1 = 字段1的值,字段2 = 字段2的值, ...;
如果只想更新或删除某些固定的记录,可以在后面添加WHERE子句进行条件过滤,如
update t_student set age = 20 where age > 23 and name != 'Rose';
5,查询数据
查询制定字段详细信息的基本格式:
SELECT 字段1,字段2,... FROM 表名;
查询所有字段信息:
SELECT * FROM 表名;
后面也可以增加WHERE子句过滤,如
SELECT * FROM t_student WHERE age > 23;
SQLite3支持C语言,我们就是使用一套C语言接口才能在Xcode中使用SQLite3。在Xcode中操作数据库需要经过3个步骤,并且每个步骤都需要调用特定的C函数:
下面使用SQLite3开发一个存储学生信息的示例程序:
–没写过,也是从书上抄来的
1,在程序中添加一个libsqlite3.dylib包,它包含了使用SQLite3所需的C函数接口:
方法:选中工程→“Targets”→“General”→“Linked Frameworks and Libraries”,然后搜索框中输入sqlite,选中后点击“add”即可。
2,搭建界面,关联控件对象
使用xib,搭界面,姓名输入框,年龄输入框,学号输入框,保存按钮等空间设置好。
3,打开数据库,创建数据库
在viewDidLoad方法中实现数据库的连接,并在数据库中创建一个数据表:
- (void)viewDidLoad{
[super viewDidLoad];
//获取沙盒路径
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//创建数据库路径
NSString *dataBasePath = [docDir stringByAppendingPathComponent:@"database.sqlite"];
//如果数据库存在就会返回数据库,如果数据库不存在则会创建一个新的数据库返回
int result = sqlite3_open([dataBasePath UTF8String], &db);
//判断数据库是否成功打开
if (result == SQLITE_OK) {
NSLog(@"打开数据库成功");
NSLog(@"%@",dataBasepath);
}else {
NSLog(@"打开数据库失败");
}
const char *sql = "CREATE TABLE IF NOT EXISTS t_student(id integer PRIMARY KEY AUTOINCREMENT,name text NOT NULL, age INTEGER NOT NULL, number text NOT NULL);"
char *errmsg = NULL;
result = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (result == SQLITE_OK) {
NSLog(@"创表成功");
}else {
NSLog(@"创表失败--%s--%s--%d",errmsg,__FILE__,__LINE__);
}
}
点击保存按钮后,将数据保存到数据表中:
- (IBAction)save:(UIButton *)sender {
//获取表格中的数据
NSString *name = self.name.text;
int age = [self.age.text intValue];
NSString *number = self.number.text;
if (name && age && number) {
NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_stundent (name,age,number) VALUES ('%@','%d','%@');",name,age,number];
char *error = nil;
//执行插入sql语句
sqlite3_exec(db, sql.UTF8String, NULL, NULL, &error);
if (error) {
[self slertViewWithTitle:@"提示" message:@"添加失败" CertainButtonTitle:@"确定"];
}else {
[self slertViewWithTitle:@"提示" message:@"保存成功" CertainButtonTitle:@"确定"];
}
}else {
[self slertViewWithTitle:@"提示" message:@"请将信息填写完整" CertainButtonTitle:@"确定"];
}
}
//定义一个提示用户信息的方法
- (void)alertViewWithTitle:(NSString *)title message:(NSString *)message CertainButtonTitle:(NSString *)buttonTitle{
UIAlertView *alert = [[UIALertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:buttonTitle otherButtonTitles:nil];
[alert show];
}
查询数据之前要先检查sql语句是否正确,这需要通过函数sqlite3_prepare_v2()来实现:
sqlite3_prepare_v2(sqlite3 *db,const char *zSql, int nByte,sqlite3_stmt **ppStmt,const char **pzTail);
第一个参数sqlite3 *db表示数据库,第二个参数const char *zSql 为sql语句,第三个参数int nByte为统计zSql语句的长度,一般输入-1表示自动统计长度,第四个参数 **ppStmt用来传递数据,第五个一般设置为NULL,表示指向*zSql未使用的部分。
若查询到sql语句正确,则需要使用sqlite3_step()函数移动查询数据,此外,还有若干函数用于从查询结果中获取数据:
sqlite3_column_text ()//取text类型的数据
sqlite3_column_blob ()//取blob类型的数据
sqlite3_column_int ()//取int类型的数据
查询数据方法代码:
- (IBAction)selectStatus:(id)sender{
const char *sql = "SELECT name, age FROM t_students;";
sqlite3_stmt *stmt;//用于提取数据
//1,做查询前的准备,检查sql语句是否正确
int result = sqlite3_prepare_v2(self.db, sql, -1, &stmt, NULL);
if (result == SQLITE_OK){//准备完成,没有错误
//提取查询到的数据到stmt,一次提取一条
//如果返回值为SQLITE_ROW,就代表提取到了一条记录
whilt(sqlite3_step(stmt) == SQLITE_ROW){
//3,取出提取到的记录(数据)中的第0列的数据
const unsigned char *name = sqlite3_column_text(stmt,0);
int age = sqlite3_column_int(stmt, 1);
NSLog(@"%s %d",name,age);
}
}
sqlite3_close(self.db);
}
上述代码,程序先调用sqlite3_prepare_v2 ()函数检查sql语句的正确性,然后通过while循环,判断是否获取到数据,若获取到记录则返回记录的数据,并在程序条实况将返回的记录的数据打印出来,最后使用sqlite3_close()函数关闭数据库。