一、SQLite3
首先要添加库文件libsqlite3.dylib和导入主头文件#import <sqlite3.h>
sqlite3_open()
根据文件路径打开数据库,如果不存在,则会创建一个新的数据库
sqlite3 *db = NULL;
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"demo.sqlite"];
/**
* filename: 数据库文件的存放路径
* ppDb: 一个打开的数据库实例
* sqlite3_open()会返回一个int类型的值, 这个值代表着打开数据库是否成功,如果result等于常量SQLITE_OK,则表示成功打开数据库
*/
int result = sqlite3_open(path.UTF8String, &db);
if (result == SQLITE_OK) {
NSLog(@"--数据库打开成功--%@",path);
}
sqlite3_exec()
sqlite3_exec()
可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据
//建表
NSString *sql = @"create table if not exists t_student(id integer primary key autoincrement, name test, age integer);";
//插入数据
//NSString *sql = @"insert into t_student(name,age) values ('lisi',12)";
char *error = nil;
/**
* sqlite3*: 需要执行sql语句的数据库
* const char *sql:需要执行的sql语句
* int (*callback)(void*,int,char**,char**):执行完sql语句之后的回调方法
* void *:回调方法的参数
* char **errmsg :错误信息
*/
int execResult = sqlite3_exec(db, [sql UTF8String], NULL, NULL, &error);
if (execResult == SQLITE_OK) {
NSLog(@"成功");
}
带占位符插入数据
//插入语句
NSString *sql = @"insert into t_student(name,age) values (?,?)";
NSArray *args = @[@"wanger",@(23)];
sqlite3_stmt *stmt = nil;
//sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
if (result == SQLITE_OK) {
NSLog(@"");
}
for (int i = 0; i<args.count; i++) {
NSObject *objc = args[i];
if ([objc isKindOfClass:[NSNumber class]]) {
NSNumber *number = ( NSNumber *)objc;
if (strcmp([number objCType], @encode(int))) {
sqlite3_bind_int(stmt, i + 1, number.intValue);
}else if(strcmp([(NSNumber *)objc objCType], @encode(float))) {
sqlite3_bind_double(stmt, i + 1, number.doubleValue);
}else if(strcmp([(NSNumber *)objc objCType], @encode(double))) {
sqlite3_bind_double(stmt, i + 1, number.doubleValue);
}
}else if([objc isKindOfClass:[NSString class]]){
NSString *str = (NSString *)objc;
/**
sqlite3_stmt*,
int:占位符的位置,第一个占位符的位置是1,不是0
const char*:占位符要绑定的值
int:在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
void(*)(void*):一个可选的函数回调,一般用于在语句执行后完成内存清理工作
*/
sqlite3_bind_text(stmt, i + 1, [str UTF8String], -1, SQLITE_TRANSIENT);
}
}
/**
执行SQL语句,返回SQLITE_DONE代表成功执行完毕
*/
sqlite3_step(stmt);
/**
重置sqlite3_stmt *对象,返回SQLITE_OK代表重置成功
*/
sqlite3_reset(stmt);
/**
销毁sqlite3_stmt *对象,返回SQLITE_OK代表销毁成功
*/
sqlite3_finalize(stmt);
查询数据
//查询语句
NSString *sql = @"select id, name, age from t_student;";
sqlite3_stmt *stmt = nil;
//sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
if (result == SQLITE_OK) {
NSLog(@"");
}
NSMutableArray *arrM = [NSMutableArray array];
//sqlite3_step()返回SQLITE_ROW代表遍历到一条新记录
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 从stmt中取出提取到的数据
//获得一条数据中字段的个数
int count = sqlite3_column_count(stmt);
NSMutableDictionary *record = [NSMutableDictionary dictionary];
for (int i = 0; i < count; i++) {
//取得key值
const char *cName = sqlite3_column_name(stmt, i);
NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
//获得value的类型
int type = sqlite3_column_type(stmt, i);
switch (type) {
case SQLITE_INTEGER:
{
int number = sqlite3_column_int(stmt, i);
record[name] = @(number);
break;
}
case SQLITE_FLOAT:
{
double doubleValue = sqlite3_column_double(stmt, i);
record[name] = @(doubleValue);
}
break;
case SQLITE3_TEXT:
{
const char *textValue = sqlite3_column_text(stmt, i);
NSString *text = [NSString stringWithCString:textValue encoding:NSUTF8StringEncoding];
record[name] = text;
}
break;
case SQLITE_NULL:
record[name] = [NSNull new];
break;
default:
break;
}
}
[arrM addObject:record];
}
事务
- 如果使用 sqlite3_exec 或者, sqlite3_step()来执行sql语句, 会自动开启一个"事务", 然后, 自动提交"事务"
- 只需要手动开启事务, 手动提交事务, 这时候, 函数内部, 就不会自动开启 和提交事务,大大提高了数据库操作的效率
开启事务:begin transaction;
回滚事务:rollback;
提交事务:commit;
//查询语句
NSString *sql = @"insert into t_student(name,age) values (?,?)";
NSArray *args = @[@"wanger",@(23)];
sqlite3_stmt *stmt = nil;
//sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
if (result == SQLITE_OK) {
NSLog(@"");
}
/** 开启事务 */
NSString *beginSql = @"BEGIN TRANSACTION";
sqlite3_exec(db, beginSql.UTF8String, nil, nil, nil);
for (int i = 0; i< 1000000; i++) {
for (int i = 0; i<args.count; i++) {
NSObject *objc = args[i];
if ([objc isKindOfClass:[NSNumber class]]) {
NSNumber *number = ( NSNumber *)objc;
if (strcmp([number objCType], @encode(int))) {
sqlite3_bind_int(stmt, i + 1, number.intValue);
}else if(strcmp([(NSNumber *)objc objCType], @encode(float))) {
sqlite3_bind_double(stmt, i + 1, number.doubleValue);
}else if(strcmp([(NSNumber *)objc objCType], @encode(double))) {
sqlite3_bind_double(stmt, i + 1, number.doubleValue);
}
}else if([objc isKindOfClass:[NSString class]]){
NSString *str = (NSString *)objc;
/**
sqlite3_stmt*,
int:占位符的位置,第一个占位符的位置是1,不是0
const char*:占位符要绑定的值
int:在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
void(*)(void*):一个可选的函数回调,一般用于在语句执行后完成内存清理工作
*/
sqlite3_bind_text(stmt, i + 1, [str UTF8String], -1, SQLITE_TRANSIENT);
}
}
/**
执行SQL语句,返回SQLITE_DONE代表成功执行完毕
*/
sqlite3_step(stmt);
/**
重置sqlite3_stmt *对象,返回SQLITE_OK代表重置成功
*/
sqlite3_reset(stmt);
}
/** 提交事务 */
NSString *commitsql = @"COMMIT TRANSACTION";
int commitResult = sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
if (commitResult == SQLITE_OK) {
NSLog(@"--成功");
}
/**
销毁sqlite3_stmt *对象,返回SQLITE_OK代表销毁成功
*/
sqlite3_finalize(stmt);
/** 开启事务 */
NSString *sql = @"BEGIN TRANSACTION";
int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
if (result == SQLITE_OK) {
NSString *sql1 = @"update t_stu set money = money - 10 where name = 'zhangsan'";
NSString *sql2 = @"update t_stu set money = money + 10 where name = 'lisi'";
int result1 = sqlite3_exec(db, sql1.UTF8String, NULL, NULL, NULL);
int result2 = sqlite3_exec(db, sql2.UTF8String, NULL, NULL, NULL);
if (result1 == SQLITE_OK && result2 == SQLITE_OK) {
/** 提交事务 */
NSString *commitsql = @"COMMIT TRANSACTION";
sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
}else{
/** 回滚事务 */
NSString *commitsql = @"ROLLBACK TRANSACTION";
sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
}
}
网友评论