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 是线程相关的基础框架的一 ...
随机推荐
- Android App之间通过Intent交互
Android 最重要的功能之一是应用能够基于它要执行的"操作"向另一个应用发送用户. 例如,如果您的应用有您要在地图上显示的公司地址,您无需在显示地图的应用中构建 Activit ...
- Java学习之二维数组定义与内存分配详解
二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: ...
- IE下的deflate模式
浏览器有一个非常有用的特性:自动解压. 在使用AJAX请求数据的时候,数据在服务器端压缩传输,在浏览器端自动解压,请求直接得到解压后的结果. 在Request Header中,一般会列出浏览器支持的压 ...
- sql server中高并发情况下 同时执行select和update语句死锁问题 (二)
SQL Server死锁使我们经常遇到的问题,数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁.希望对您学习SQL Server死锁方面能有所帮助. 死锁对于DBA或是数据 ...
- 通过一个color创建一个image
使用的地方: [_addButton setBackgroundImage:[UIImage imageWithColor:[[UIColor whiteColor] colorWithAlphaCo ...
- Dynamics CRM 依赖组件类型为应用程序功能区导致的无法删除实体问题的解决方法
看到有人问到这个问题,这边就简单描述下解决方法,主要是针对第一次碰到这个问题云里雾里的朋友,错误如下 在我们建lookup关联的时候有下图中的这么个设置,对于很多新手默认就是下图这样不会去做改动,因为 ...
- 安卓中不同APP之间的消息通信
昨天在腾讯实习生招聘初试面试时面试官问道我关于两个APP之间相互通信的方式,当时自己回道到了contentProvider与BroadcastReceiver.但他接着问还有没有其它的方式,我跟他说可 ...
- 我也来写spring
本文可作为北京尚学堂 spring课程的学习笔记 我们还是用上一篇文章的例子 给数据库中增加一个user 整体代码如下 package com.bjsxt.test; import com.bjsxt ...
- Mybatis事务(二)事务隔离级别
一般数据库的隔离级别有4个,由低到高依次为Read uncommitted.Read committed.Repeatable read.Serializable,这四个级别可以逐个解决脏读.不可重复 ...
- 【Swift学习笔记00】——enumeration枚举类型遵循协议protocol
Apple官方文档:The Swift Programming LanguageProtocols and Extensions一节的小节练习,要求自行定义一个enumeration枚举类型,并且遵循 ...