iOS下FMDB的多线程操作(二)
上一篇记录不使用FMDatabaseQueue来使用多线程,这一篇记录一下使用FMDatabaseQueue的方式。
需要注意的时queue操作中不能嵌套queue操作,否则会各种错误。
当使用FMDatabaseQueue,因为整个项目用同一个queue,所以最好写一个单例。我是这么写的,不知道是否合理,先记录吧。
下面是头文件。
@interface JKDataBase : NSObject @property (nonatomic, retain, readonly) FMDatabaseQueue *dbQueue; + (JKDataBase *)shareInstance;
.m文件就贴一下关键代码。
static JKDataBase *_instance = nil; + (instancetype)shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init] ;
}) ; return _instance;
} - (FMDatabaseQueue *)dbQueue
{
if (_dbQueue == nil) {
NSString* docsdir = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSFileManager *filemanage = [NSFileManager defaultManager];
docsdir = [docsdir stringByAppendingPathComponent:@"FMDBDemo"];
BOOL isDir;
BOOL exit =[filemanage fileExistsAtPath:docsdir isDirectory:&isDir];
if (!exit || !isDir) {
[filemanage createDirectoryAtPath:docsdir withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString* dbpath = [docsdir stringByAppendingPathComponent:@"myDB.sqlite"];
_dbQueue = [[FMDatabaseQueue alloc] initWithPath:dbpath];
}
return _dbQueue;
}
然后就是User类中的数据库操作。同样也是创建表、插入、删除、更新、查询五类操作。
1、创建数据库表
/** 创建表 */
+ (BOOL)createUserTable
{
__block BOOL res = NO;
JKDataBase *jkDB = [JKDataBase shareInstance];
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = @"CREATE TABLE IF NOT EXISTS User(ID INTEGER PRIMARY KEY, name TEXT, age INTEGER, ID_No TEXT);";
res = [db executeUpdate:sql];
}];
return res;
}
2、插入数据
- (BOOL)save
{
JKDataBase *jkDB = [JKDataBase shareInstance];
__block BOOL res = NO;
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = [NSString stringWithFormat:@"INSERT INTO User(name, age, ID_No) VALUES ('%@', '%d', '%@');", self.name, self.age, self.ID_no];
res = [db executeUpdate:sql];
}];
return res;
} /** 批量保存用户对象 */
+ (BOOL)saveObjects:(NSArray *)array
{
__block BOOL res = YES;
JKDataBase *jkDB = [JKDataBase shareInstance];
// 如果要支持事务
[jkDB.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (User *user in array) {
NSString *sql = [NSString stringWithFormat:@"INSERT INTO User(name, age, ID_No) VALUES ('%@', '%d', '%@');", user.name, user.age, user.ID_no];
if (![db executeUpdate:sql]) {
res = NO;
*rollback = YES;
return;
}
}
}];
return res;
}
3、更新数据
- (BOOL)update
{
JKDataBase *jkDB = [JKDataBase shareInstance];
__block BOOL res = NO;
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = [NSString stringWithFormat:@"UPDATE User SET name = '%@',age = '%d',ID_no = '%@' WHERE ID = '%d';", self.name, self.age, self.ID_no, self.ID];
res = [db executeUpdate:sql];
}];
return res;
} /** 批量更新用户对象*/
+ (BOOL)updateObjects:(NSArray *)array
{
__block BOOL res = YES;
JKDataBase *jkDB = [JKDataBase shareInstance];
// 如果要支持事务
[jkDB.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (User *user in array) {
NSString *sql = [NSString stringWithFormat:@"UPDATE User SET name = '%@',age = '%d',ID_no = '%@' WHERE ID = '%d';", user.name, user.age, user.ID_no, user.ID];
BOOL flag = [db executeUpdate:sql];
if (!flag) {
res = NO;
*rollback = YES;
return;
}
}
}];
return res;
}
4、删除数据
- (BOOL)deleteObject
{
JKDataBase *jkDB = [JKDataBase shareInstance];
__block BOOL res = NO;
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = [NSString stringWithFormat:@"DELETE FROM User WHERE ID = '%d'",self.ID];
res = [db executeUpdate:sql];
}];
return res;
} /** 批量删除用户对象 */
+ (BOOL)deleteObjects:(NSArray *)array
{
__block BOOL res = YES;
JKDataBase *jkDB = [JKDataBase shareInstance];
// 如果要支持事务
[jkDB.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (User *user in array) {
NSString *sql = [NSString stringWithFormat:@"DELETE FROM User WHERE ID = '%d'",user.ID];
BOOL flag = [db executeUpdate:sql];
if (!flag) {
res = NO;
*rollback = YES;
return;
}
}
}];
return res;
}
5、查询数据
+ (NSArray *)findAll
{
JKDataBase *jkDB = [JKDataBase shareInstance];
NSMutableArray *users = [[NSMutableArray alloc] init];
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = @"SELECT * FROM User";
FMResultSet *resultSet = [db executeQuery:sql];
while ([resultSet next]) {
User *user = [[User alloc] init];
user.ID = [resultSet intForColumn:@"ID"];
user.name = [resultSet stringForColumn:@"name"];
user.age = [resultSet intForColumn:@"age"];
user.ID_no = [resultSet stringForColumn:@"ID_no"];
[users addObject:user];
[user release];
}
}]; return [users autorelease];
} /** 查找某个用户 */
+ (instancetype)findFirstBySql:(NSString *)sql
{
User *user = nil;
NSArray *users = [self findBySql:sql];
if (users.count > 0) {
user = [users firstObject];
}
return user;
} /** 查找用户 */
+ (NSArray *)findBySql:(NSString *)sql
{
JKDataBase *jkDB = [JKDataBase shareInstance];
NSMutableArray *users = [[NSMutableArray alloc] init];
[jkDB.dbQueue inDatabase:^(FMDatabase *db) {
NSString *select = @"SELECT * FROM User ";
if (sql) {
select = [select stringByAppendingString:sql];
}
FMResultSet *resultSet = [db executeQuery:select];
while ([resultSet next]) {
User *user = [[User alloc] init];
user.ID = [resultSet intForColumn:@"ID"];
user.name = [resultSet stringForColumn:@"name"];
user.age = [resultSet intForColumn:@"age"];
user.ID_no = [resultSet stringForColumn:@"ID_no"];
[users addObject:user];
[user release];
}
}]; return [users autorelease];
}
先记录这么多吧,希望能对别人有所帮助。
demo传送门:http://download.csdn.net/detail/u011619283/8838965
iOS下FMDB的多线程操作(二)的更多相关文章
- iOS下FMDB的多线程操作(一)
iOS中一些时间比较长的操作都应该放在子线程中,以避免UI的卡顿.而sqlite 是非线程安全的,故在多线程中不能共用同一个数据库连接,否则会导致EXC_BAD_ACCESS.所以我们可以在子线程中创 ...
- iOS——使用FMDB进行数据库操作(转载)
iOS 使用FMDB进行数据库操作 https://github.com/ccgus/fmdb [摘要]本文介绍iOS 使用FMDB进行数据库操作,并提供详细的示例代码供参考. FMDB 使用方法 A ...
- iOS下WebRTC音视频通话(二)-局域网内音视频通话
这里是iOS 下WebRTC音视频通话开发的第二篇,在这一篇会利用一个局域网内音视频通话的例子介绍WebRTC中常用的API. 如果你下载并编译完成之后,会看到一个iOS 版的WebRTC Demo. ...
- sqlite:多线程操作数据库“database is locked”解决方法(二)
上一篇博客<sqlite:多线程操作数据库“database is locked”解决方法>通过注册延时函数的方法来处理数据库被锁的问题.此方法固然能解决问题,但是在多个线程向数据库写入大 ...
- swift语言之多线程操作和操作队列(下)———坚持51天吃掉大象(写技术文章)
欢迎有兴趣的朋友,参与我的美女同事发起的活动<51天吃掉大象>,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章.关注她的微信公众号: ...
- Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作
详细的Spring MVC框架搭配在这个连接中: Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 这篇主 ...
- spa(单页应用)中,使用history模式时,微信长按识别二维码在ios下失效的问题
spa(单页应用,vue)中,使用history模式时,微信长按识别二维码在ios下失效的问题. 触发条件: spa单页应用: 路由模式 history 从其他页面跳转到带有微信二维码识别的页面(不是 ...
- linux下oracle11G DG搭建(二):环绕主库搭建操作
linux下oracle11G DG搭建(二):环绕主库搭建操作 环境 名称 主库 备库 主机名 bjsrv shsrv 软件版本号 RedHat Enterprise5.5.Oracle 11g 1 ...
- 移动开发在路上-- IOS移动开发系列 多线程二
最近太忙没太多的时间,忙碌的码农生活空下来一点时间,都会挤出来看一些技术或者咨询的文章,废话不多说,直奔主题. 接着上一次的继续说. 定时器在多线程的使用 NSRunLoop 是线程相关的基础框架的一 ...
随机推荐
- Cocos2D在新版Swift中常量枚举值引用代码的修改
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在SpriteBuilder中是无法直接给一个CCB文 ...
- Spring入门介绍-AOP(三)
AOP的概念 AOP是面向切面编程的缩写,它是一种编程的新思想.对我们经常提起的oop(面对对象编程)有一定的联系. AOP和OOP的关系 AOP可以说是oop的某一方便的补充,oop侧重于对静态的属 ...
- [ExtJS5学习笔记]第二十一节 Extjs5中使用config配置给ext.widget或者create方法传递参数
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39252805 官方例子:http://docs.sencha.com/extjs/5. ...
- Java并发框架——公平性
所谓公平性指所有线程对临界资源申请访问权限的成功率都一样,不会让某些线程拥有优先权.通过前面的CLH Node FIFO学习知道了等待队列是一个先进先出的队列,那么是否就可以说每条线程获取锁时就是公平 ...
- Android初级教程理论知识(第八章网络编程二)
HttpClient 发送get请求 创建一个客户端对象 HttpClient client = new DefaultHttpClient(); 创建一个get请求对象 HttpGet hg = n ...
- MBR和GPT概要学习
MBR和GPT概要学习 1. MBR和GPT 大家所最为熟知的分区方式同时也是最主流的主要有两种:MBR(Master Boot Record)和GPT(GUID Partition Tabl ...
- SQL Server性能优化与管理的艺术 附件下载地址
首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...
- Touch Handling in Cocos2D 3.x(六)
使英雄变成可触碰的对象 这是另一个非常有用的特性.很多用户需要捡起已经存在的英雄然后满屏幕移动它们.让我们按以下步骤实现该功能: 如果用户触摸屏幕空白位置,一个新的英雄将被创建 如果用户触摸一个已经存 ...
- spring mvc接收List集合、JUI传JSP List
JUI页面是这样的 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 <div class=&quo ...
- 下载Ext JS 5.1 gpl版本的方法
先进入官网:http://www.sencha.com 然后在导航的Products中选择Sencha Ext JS,会看到以下页面: 这时候不要单击Download按钮,而是要单击导航中的DETAI ...