一、前言
sqlite3数据库是一种轻量型的数据库,系统中已经默认安装了,可以通过终端来查看:
首先进入模拟器的沙盒目录中,我们在Documents目录下创建一个sql文件,然后使用sqlite3来访问这个文件。在终端中,可 以使用sql语句来对表进行操作,这里就不在赘述了,下面主要介绍使用代码来对表进行操作。
二、使用代码对数据库进行增、删、改、查。
2.1 导入头文件
首先在工程下的BuildPHases下找到LinkBinary....什么的,然后点击下面的加号,添加sql的库,我们选择添加的是第二个搜索结果。
然后再用到数据库的类中导入即可
#import <sqlite3.h>
由于OC里面有关数据库的操作都是基于C语言的,所以有可能不会提示。
2.2 正式使用
1. 打开数据库
-(void)open{
//filename:数据库的具体路径
//ppdb:数据库实例的地址
NSString * filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"db.sql"];
int status = sqlite3_open(filePath.UTF8String, &_db);
if(status == SQLITE_OK){
//打开成功
NSLog(@"打开成功");
}else{
NSLog(@"打开失败");
}
}
首先我们在Documents目录下需要创建一个名为 db.sql 的文件,所以我们拼接出这个文件的路径。然后使用 sqlite_open的方法,这个方法接受两个参数,一个是数据库的具体的路径,第二个是数据库实例的地址。在之前已提过OC中的数据库的操作都是基于C语言的,所以两个参数的都是C语言中的类型,需要转化。这个方法调用之后,会将数据库实例的地址放入我们定义的属性变量 db 中(注意这个属性变量也是C语言类型的指针,所以用assign来修饰),这个方法返回一个状态值,表示数据打开成功与否。
2. 创建表
-(void)createTable{
//1.创建sql语句
NSString * sql = @"create table student (id integer primary key autoincrement,name text,age integer)";
//2.执行语句
int status = sqlite3_exec(self.db, sql.UTF8String,NULL, NULL, NULL);
if (status == SQLITE_OK) {
NSLog(@"创建表成功");
}else{
NSLog(@"创建表失败");
}
}
使用sqlite3_exec()方法来执行一个sql语句,它接受五个参数,第一个参数就是这个数据库的实例,第二个就是执行的sql语句,第三个参数是一个函数指针,就是sql语句执行成功之后执行的回调函数,相当于OC中的block,第四个参数是一个任意类型的指针表示第一个需要回调的参数,最后一个参数表示的错误信息。这个方法返回一个状态值,表示创建表是否成功。
3. 向表中插入,删除,更改数据
-(void)insert{
NSString * sql = @"insert into student(name,age) values('Jack',20)";
if(sqlite3_exec(self.db,sql.UTF8String, NULL, NULL, NULL)==SQLITE_OK){
NSLog(@"插入数据成功");
}else{
NSLog(@"插入数据失败");
}
}
我们向数据库中插入一条数据,也是通过哦 sqlite3_exec()函数来完成,完成后可以通过访问沙盒路径下的sql文件来查看数据是否已经被插入表中。同理删除,更改数据只是sql语句的不同,这里不再赘述。
4. 查询数据
-(void)select{
//1.定义查询语句
NSString * sql = @"select * from student";
//2.准备查询语句(预处理) 将数据缓存到另外一个地方去->stmt
sqlite3_stmt * stmt = NULL;
if (sqlite3_prepare(self.db, sql.UTF8String, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(@"预处理成功");
//3.一条条读数据
while (sqlite3_step(stmt)==SQLITE_ROW) {
char * name = (char *) sqlite3_column_text(stmt, 1);
int age = (int) sqlite3_column_int(stmt, 2);
NSData * data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:sqlite3_column_bytes(stmt, 3)];
UIImage * imag = [UIImage imageWithData:data];
NSLog(@"%s,%d,%@",name,age,imag);
}
}else{
NSLog(@"预处理失败");
}
//释放开辟的内存空间
sqlite3_finalize(stmt);
}
查询语句相对上面的三种操作来说稍微复杂一些,我们一步步来说,首先是定义查询语句,然后是对sql语句进行预处理,在预处理的过程中,我们定义了一个 sqlite3_stmt类型的变量 stmt,这里有点像 servlet中的PreparedStatement,定义这个变量的原因是将查询所得的数据放到这个变量中。然后调用 sqlite3_prepare()这个方法,这个方法接受五个参数,前两个参数不再赘述,第三个参数指的是sql语句的长度,我们传-1表示计算机自己计算sql语句的长度,第四个参数就是 stmt的地址,这个函数将查询到的结果集放入这个地址指向的空间中,最后一个参数指向未执行的SQL语句。然后循环读取stmt中的数据,通过 sqlite3_step(stmt) 来判断stmt是否遍历结束了,然后通过 sqlite3_column_xxxx() 来获取相应的数据,如果获取的数据包含图片,视频等数据,需要将查询的结果转换为二进制, 通过sqlite3_column_bytes() 来计算这个字段(图片,视频)字段的字节数。最后使用 sqlite3_finalize()方法来释放掉这个指针指向的空间。
5. 插入图片,视频,音频数据
-(void)multipleInsert{
UIImage * image = [UIImage imageNamed:@"1"];
NSData * imgeData = UIImagePNGRepresentation(image);
NSLog(@"%@",imgeData);
//占位符 ?
NSString * sql = @"insert into student(name,age,icon) values(?,?,?)";
//预处理
sqlite3_stmt * stmt = NULL;
if(sqlite3_prepare(self.db, sql.UTF8String,-1,&stmt, NULL)==SQLITE_OK){
NSLog(@"预处理成功");
//绑定数据
sqlite3_bind_text(stmt, 1,"Harry",-1, NULL);
sqlite3_bind_int(stmt, 2, -1);
sqlite3_bind_blob(stmt, 3,imgeData.bytes,(int)imgeData.length, NULL);
//将绑定的数据保存到数据库中
if(sqlite3_step(stmt)==SQLITE_DONE){
NSLog(@"保存成功");
}else{
NSLog(@"保存失败");
}
}else{
NSLog(@"预处理失败");
}
//释放开辟的内存空间
sqlite3_finalize(stmt);
}
这里以插入图片数据为例,首先我们将图片转化为二进制数据,然后定义sql语句,这里使用使用占位符来表示对应字段的值,因为图片的二进制数据很多,不能直接拼接进去。接着进行预处理,预处理成功之后,通过 sqlite3_bind_xxxx()方法来将不同类型的数据绑定到对应占位符上,然后 调用 sqlite3_step(stmt) 方法来进行具体操作,这个方法返回一个状态值,表示所进行的操作是否成功。同样 需要释放stmt的空间。