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 是线程相关的基础框架的一 ...
随机推荐
- C++ ifstream,ofstream读写二进制文件
为什要吧数据存为二进制 这个嘛,是我个人习惯,一般,我们会把日志文件存为文本文件.数据文件存成二进制文件. 其实,我们接触的文件,比如图像.视频都是以二进制的形式存储的,要想查看这类数据,必须知道数据 ...
- Xcode7.3.1中通过最新的CocoaPod安装pop动画引擎
CocoaPod是一个用ruby实现,用于方便的管理Xcode中第三方插件的管理器.用它我们可以很方便的安装和升级插件而不用担心破坏原有的项目. 而pop是一个用于实现App中动画的引擎,它是由Fac ...
- 20ViewPager demo1,2:接收ViewPager展示View的使用
Demo1 MainActivity .JAVA package com.qf.day20_viewpager_demo1; import java.util.ArrayList; import ja ...
- Java基本语法-----java数据类型的转换
前言 Java中可以进行不同数据类型的加减乘除运算吗?是可以的.在算术运算符中已经体验过如果两个整数(int)相除会去掉小数部分.如果需要保留小数部分,可以让除数或者被除数变为double类型的(5变 ...
- LMAX高并发系统架构
很早就看到过MF的这篇The LMAX Architecture,可是之前一来英文水平不够,二来确实看不懂- 今天有幸再次看到,一口气读完终于有所领悟. 1 Overall Architecture ...
- UNIX网络编程——原始套接字的魔力【续】
如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...
- Dynamics CRM Plugin DLL恢复工具
本篇接上篇继续介绍XrmToolBox中的某项功能,该工具的下载见上篇博文. 打开XrmToolBox,找到Assembly Recovery Tool,点击进去 如何连接上你的组织继续不表,列表中显 ...
- mysql-workbench工具update(更新)失败的解决办法
是因为安全模式的保护,所以我们需要设置一下: 如下:windows下是edit–>preferences–>SQL Editor 把右边的最后一行,"safe update&qu ...
- 【Unity技巧】四元数(Quaternion)和旋转
四元数介绍 旋转,应该是三种坐标变换--缩放.旋转和平移,中最复杂的一种了.大家应该都听过,有一种旋转的表示方法叫四元数.按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法--矩阵旋转和欧拉旋转. ...
- Linux内核分配内存的方式
page = alloc_pages(GFP_KERNEL, get_order(1234));分配失败返回NULLGFP_KERNEL ---> 分配标志,当没有足够内存分配时,睡眠阻塞,直 ...