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 是线程相关的基础框架的一 ...
随机推荐
- SSH框架实现仿淘宝购物demo
还记得六月份实习的时候,曾经做过一个电商的项目,项目里面需要实现类似淘宝购物车的移动端的demo,随着项目的进行,再一次跟购物车碰面,但是今天呢,不是移动端的需求,如何使用SSH框架实现类似淘宝的购物 ...
- Android开发学习之路--RxAndroid之操作符
学习了RxAndroid的一些基本知识,上篇文章也试过了RxAndroid的map操作符,接着来学习更多的操作符的功能吧. 操作符就是为了解决对Observable对象的变换的问题,操作符用于 ...
- Android初级教程:shape的基本用法
转载本文请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203347 点击打开链接 在自定义进度条之前,先来学习一下shape的用 ...
- Intent和PendingIntent的区别
intent英文意思是意图,pending表示即将发生或来临的事情. PendingIntent这个类用于处理即将发生的事情.比如在通知Notification中用于跳转页面,但不是马上跳转. I ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(四):创建TexturePacker自动脚本
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- 关于bootstrap-fileinput
最近搞了一个很简单的项目,里面需要文件上传.当然文件上传也是很简单的,不过做出成品之后发现,卧槽,火狐和谷歌两个浏览器显示的内容不一致. 如下图,左边的是谷歌显示,右边是火狐显示. 其实,作为一个后台 ...
- Android的TabHost组件-android的学习之旅(四十)
TabHost简介 虽然,官方建议用Fagment取代TabHost,但是我们还是大概的介绍一下.TabHost是一种非常简单的组件,TabHost可以很方便的在窗口放置多个标签页,每一个标签页相当于 ...
- popupwindow和listview
在使用PopupWindow的时候,有一个不好的地方就是不太好设置弹出窗体的大小.如果指定绝对大小,那么对于不同分辨率不同尺寸的手机来说,显示出来效果会不同,从而导致用户体验不佳. 为了达到Popup ...
- 常用js总结
通过radio来显示/隐藏一个div <div id="ArbAcei" > <br/> 有无不良反应停药 <input type="rad ...
- 摆脱命令行,Ubuntu下配置Android开发环境
作者:宋志辉 微博:weibo.com/askzhihui/ 安装所需工具 一.新立得 新立得(Synaptic)是Debian和Ubuntu Linux操作系统的包管理工具apt的图形化前端. 它结 ...