
FMDB
FMDB的FMDatabaseQueue底层是用GCD的串行队列调度数据库在同步函数里面操作数据的.
FMDatabaseQueueManager
设计单例模式
1 2 3 4 5 6
|
@interface : FMDatabaseQueue + (instancetype)sharedManager; @end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
+(instancetype)sharedManager { static FMDatabaseQueueManager *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSString *SQLPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"my.db"]; instance = [FMDatabaseQueueManager databaseQueueWithPath:SQLPath]; [instance inDatabase:^(FMDatabase *db) { BOOL isCreate = [db executeUpdate:@"create table if not exists t_person(id integer primary key,name text not null,age integer)"]; if (isCreate) { NSLog(@"建表成功"); } }]; }); return instance; }
|
FMDB增删改查
-
导入头文件 #import "FMDB.h"
-
操作的类 FMDatabase 单线程时使用
-
全局的静态数据库对象
1
|
static FMDatabase *_db;
|
创建数据库和表
- 数据库的创建和建表只需要执行一次.
initialize : 这个类在第一次使用时就被调用一次,后面就不会再调用;而且是先于实例化方法调用的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
+ (void)initialize { NSString *SQLPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"heros.db"]; _db = [FMDatabase databaseWithPath:SQLPath]; BOOL isOpen = [_db open]; if (isOpen) { BOOL isCreate = [_db executeUpdate:@"create table if not exists t_heros(id integer primary key,name text not null,age integer)"]; if (isCreate) { NSLog(@"建表成功"); } } }
|
新增
1
|
[_db executeUpdateWithFormat:@"insert into t_heros(name,age) values('张三',18)"];
|
修改
1
|
[_db executeUpdateWithFormat:@"update t_heros set age = 19 where name = '张三'"];
|
删除
1
|
[_db executeUpdateWithFormat:@"delete from t_heros where name = '张三'"];
|
查询 – 模糊查询
1 2 3 4 5 6 7 8 9 10
|
FMResultSet *resultSet = [_db executeQuery:@"select * from t_heros"]; while ([resultSet next]) { NSString *name = [resultSet stringForColumn:@"name"]; int age = [resultSet intForColumn:@"age"]; }
|
如果数据库里面的记录有很多条
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
+ (NSArray *)selectHeros { NSMutableArray *tmpM = [NSMutableArray array]; FMResultSet *resultSet = [_db executeQuery:@"select * from t_heros"]; while ([resultSet next]) { Heros *hero = [[Heros alloc] init]; NSString *name = [resultSet stringForColumn:@"name"]; int age = [resultSet intForColumn:@"age"]; hero.name = name; hero.age = @(age); [tmpM addObject:hero]; } return tmpM.copy; }
|
增删改查和事务
1 2 3 4 5 6
|
@interface ViewController () { FMDatabaseQueueManager *_manager; } @end
|
1 2 3 4 5
|
- (void)viewDidLoad { [super viewDidLoad]; _manager = [FMDatabaseQueueManager sharedManager]; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self transaction]; }
|
事务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
- (void)transaction { double start = CACurrentMediaTime(); NSString *insertSQL = @"insert into t_person(name,age) values(?,?);"; [_manager inTransaction:^(FMDatabase *db, BOOL *rollback) { for (NSInteger i = 0; i < 1000; i++) { BOOL isOK = [db executeUpdate:insertSQL,@"张三",@(100)]; if (!isOK) { *rollback = YES; break; } } }]; NSLog(@"%f",CACurrentMediaTime()-start); }
|
查询语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
- (void)query { NSString *updateSQL = @"select name,age from t_person;"; [_manager inDatabase:^(FMDatabase *db) { FMResultSet *resultSet = [db executeQuery:updateSQL]; while ([resultSet next]) { NSString *name = [resultSet stringForColumn:@"name"]; int age = [resultSet intForColumn:@"age"]; NSLog(@"%@ -- %d",name,age); } }]; }
|
删除语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
- (void)delete { NSString *updateSQL = @"delete from t_person where id = ?;"; [_manager inDatabase:^(FMDatabase *db) { BOOL isOK = [db executeUpdate:updateSQL,@(6)]; if (isOK) { NSLog(@"删除数据成功"); } else { NSLog(@"删除数据失败"); } }]; }
|
修改语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
- (void)update { NSString *updateSQL = @"update t_person set name = ?,age = ? where id = ?;"; [_manager inDatabase:^(FMDatabase *db) { BOOL isOK = [db executeUpdate:updateSQL,@"王五",@(19),@(3)]; if (isOK) { NSLog(@"更新数据成功"); } else { NSLog(@"更新数据失败"); } NSLog(@"影响行数 %d", db.changes); }]; }
|
新增语句 (预编译 : 正确的方式)
- 使用
预编译指令来插入数据
- 所谓预编译,提前对 SQL 语句检查并且缓存住
- 使用 ? 占位
- 字符串不需要 单引号
- 在执行的时候,使用
executeUpdate的参数替换 ?
- 提示 : 今后工作中,所有的 SQL 执行,都一定用预编译指令!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
- (void)insert03 { NSString *name = @"李四',0);"; NSString *insertSQL = @"insert into t_person(name,age) values(?,?);"; [_manager inDatabase:^(FMDatabase *db) { BOOL isOK = [db executeUpdate:insertSQL,name,@(18)]; if (isOK) { NSLog(@"新增数据成功"); } else { NSLog(@"新增数据失败"); } NSLog(@"自增长 ID: %zd", db.lastInsertRowId); }]; }
|
新增语句 (SQL注入 : 会出错)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
- (void)insert02 { NSString *name = @"李四',0);"; NSString *insertSQL = [NSString stringWithFormat:@"insert into t_person(name,age) values('%@',18);",name]; NSLog(@"%@",insertSQL); [_manager inDatabase:^(FMDatabase *db) { BOOL isOK = [db executeUpdate:insertSQL]; if (isOK) { NSLog(@"新增数据成功"); } else { NSLog(@"新增数据失败"); } }]; }
|
新增数据 (不靠谱)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
- (void)insert01 { NSString *name = @"李四"; NSString *insertSQL = [NSString stringWithFormat:@"insert into t_person(name,age) values('%@',18);",name]; [_manager inDatabase:^(FMDatabase *db) { BOOL isOK = [db executeUpdate:insertSQL]; if (isOK) { NSLog(@"新增数据成功"); } else { NSLog(@"新增数据失败"); } }]; }
|
近期评论