sqlite3是纯C语言的库,我们需要使用C语法使用它,使用过程如下:
1:工程添加sqlite3.0.sqlite,它总是代表最新的sqlite3的库;类中添加#import <sqlite3.h>
2:使用sqlite3_open打开数据库
3:对于无返回值的sql操作,使用sqlite3_exec函数
4:对于有返回值的查询操作,首先使用sqlite3_prepare_v2预编译,将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt,该结构体中包含了将要执行的的SQL语句的信息),使用sqlite3_bind_xxx进行参数绑定,然后使用sqlite3_step依此得到查询结果每一行数据,通过sqlite3_column_xxx 取出数据,最后释放句柄
打开或者创建数据库
- (void)viewDidLoad { [super viewDidLoad]; NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *dbPath = [dirPath stringByAppendingPathComponent:@"mydb.db"]; NSLog(@"%@",dbPath); //如果有数据库则直接打开,否则创建并打开(注意filePath是ObjC中的字符串,需要转化为C语言字符串类型) if(SQLITE_OK != sqlite3_open(dbPath.UTF8String, &_database)) { NSLog(@"error open"); } //sqlite3_close(_database); }
代码执行后沙盒document目录下会多出一个mydb.db文件,我们可以通过终端在沙盒document目录下执行sqlite3 mydb.db 命令查看db内容
添加数据库表
- (IBAction)createDBTable:(id)sender { const char *createSQL = "create table user(id integer primary key autoincrement,name text,gender text,address text)"; char *error; if(SQLITE_OK != sqlite3_exec(_database, createSQL, NULL, NULL, &error)) { NSLog(@"error create");
sqlite3_free(error); } }
sqlite3支持以下五种格式数据:
NULL: 表示该值为NULL值。
INTEGER: 无符号整型值。
REAL: 浮点值。
TEXT: 文本字符串,存储使用的编码方式为UTF-8、UTF-16BE、UTF-16LE。
BLOB: 存储二进制数据
在终端执行.tables和.schema user可以查看当前数据库拥有的表以及表结构
添加数据
- (IBAction)saveObj:(id)sender { NSString *sqlStr = [NSString stringWithFormat:@"insert into user(name,gender,address) values ('%@','%@','%@')",@"zaglitao",@"gender",@"浙江"]; const char *saveSQL = sqlStr.UTF8String; char *error; if(SQLITE_OK != sqlite3_exec(_database, saveSQL, NULL, NULL, &error)) { NSLog(@"error create");
sqlite3_free(error); } }
在终端执行select * from user可以查看添加的数据
修改数据
- (IBAction)changeObj:(id)sender { NSString *sqlStr = [NSString stringWithFormat:@"update user set name='%@',address='%@' where name='%@'",@"zanglitao",@"杭州",@"zaglitao"]; const char *updateSQL = sqlStr.UTF8String; char *error; if(SQLITE_OK != sqlite3_exec(_database, updateSQL, NULL, NULL, &error)) { NSLog(@"error create");
sqlite3_free(error); } }
删除数据
- (IBAction)deleteObj:(id)sender { NSString *sqlStr = [NSString stringWithFormat:@"delete from user where name='%@'",@"zanglitao"]; const char *deleteSQL = sqlStr.UTF8String; char *error; if(SQLITE_OK != sqlite3_exec(_database, deleteSQL, NULL, NULL, &error)) { NSLog(@"error create");
sqlite3_free(error); } }
上面的4中操作除了sql语句不同,执行的逻辑完全一致,我们自己使用时可以进行统一的封装,其中用到的关键函数sqlite3_exec:
SQLITE_API int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ );
这个接口是最常用到的,几乎除了查询之外的 sql 命令都可以用它来操作,比如创建表,插入/更新/删除记录,创建/提交/回滚事务等。
注意:如果 errmsg 不为 null,那么当错误发生时, sqlite 就会为错误消息分配内存,返回给调用者,调用者有责任调用 sqlite3_free 来释放这部分内存。
事务相关的操作也可以使用这个方法执行,具体语句如下:
创建事务的语句:BEGIN EXCLUSIVE TRANSACTION;
提交事务的语句:COMMIT TRANSACTION;
回滚事务的语句:ROLLBACK TRANSACTION;
除了上面只执行一句sql语句,不需要任何返回值的数据库操作外,还有另一种最常用的数据库操作:读取
- (IBAction)getObjs:(id)sender { const char *sql = "select * from user where name like ?"; sqlite3_stmt *stmt; //预编译sql语句,stmt保留了预编译结果的引用 int quertResult = sqlite3_prepare_v2(_database, sql, -1, &stmt, NULL); //预编译成功 if (quertResult == SQLITE_OK) { //参数绑定 sqlite3_bind_text(stmt, 1, "zanglitao", -1, NULL); //sqlite3_step() has another row ready while (sqlite3_step(stmt) == SQLITE_ROW) { //取出查询结果集 //列数 int columnCount = sqlite3_column_count(stmt); for (int i = 0; i < columnCount; i++) { const char *columnname = sqlite3_column_name(stmt, i); const unsigned char *columnvalue = sqlite3_column_text(stmt, i); NSLog(@"%@:%@",[NSString stringWithUTF8String:columnname],[NSString stringWithUTF8String:columnvalue]); } } } sqlite3_finalize(stmt); }
2014-11-13 20:41:58.717 DataStoreDemo[1781:607] id:6
2014-11-13 20:41:58.718 DataStoreDemo[1781:607] name:zanglitao
2014-11-13 20:41:58.718 DataStoreDemo[1781:607] gender:gender
2014-11-13 20:41:58.719 DataStoreDemo[1781:607] address:杭州
因为sqlite3使用c语法,不如oc来得简洁,开发中常常会对sqlite3进行封装,当然也可以选择第三方优秀的库,当前比较流行的sqlite3封装库是FMDB,FMDB使用十分方便,具体教程可以查看GitHub