博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS多线程读写Sqlite问题解决
阅读量:5918 次
发布时间:2019-06-19

本文共 4087 字,大约阅读时间需要 13 分钟。

现在ios里使用的数据库一般都是Sqlite,但是使用Sqlite有个不太好的地方就是在多线程的时候,会出现问题,sqlite只能打开一个读或者写连结。这样的话多线程就会碰到资源占用的问题。

 

最开始是使用FMDB,FMDB的早期版本不能解决这个问题,后来FMDB更新了,新版本的FMDB能够很好的解决这个多线程使用Sqlite 。

FMDB github网址  https://github.com/ccgus/fmdb 最新版的请到github取下载。

 

本文演示了使用FMDB通过多线程来读和写数据库操作。

1.建立数据库表,我采用的是Firefox的Sqlite manager 来建立的。

  建表sql如下

 CREATE TABLE "tbl_user" ("_id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "name" VARCHAR(30), "password" VARCHAR(30))

 

 2. 建立数据表的映射实体UserEntity

#import <Foundation/Foundation.h>
@interface UserEntity : NSObject
{
    
int _id;
    NSString *name;
    NSString *password;
}
@property (nonatomic, assign)
int ID;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *password;

@end 

 

3. 建立操作数据库的dao

//
//
  DbDao.m
//
  SqliteTest
//
//
  Created by foxwang on 12-4-9.
//
  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//
#import 
"
DbDao.h
"
#import 
"
DbFileManager.h
"
#import 
"
FMDatabase.h
"
#import 
"
FMDatabaseAdditions.h
"
#import 
"
FMDatabasePool.h
"
#import 
"
FMDatabaseQueue.h
"
#import 
"
UserEntity.h
"
static DbDao *gSharedInstance = nil;
@implementation DbDao
@synthesize dbFile;
@synthesize dbQueue;
+(DbDao *)sharedInstance
{
    @synchronized(self)
    {
        
if (gSharedInstance == nil)
            gSharedInstance = [[DbDao alloc] init];
    }
    
return gSharedInstance;    
}
- (
void)dealloc
{
    [self.dbFile release];
    self.dbQueue = nil;
    [super dealloc];
}
- (
id)init
{
    
    self = [super init];
    
if (self)
    {
        self.dbFile = [DbFileManager dbFilePath];
        self.dbQueue = [FMDatabaseQueue databaseQueueWithPath:self.dbFile];
        
        
    }
    
return  self;
}
- (UserEntity *)rsToUser:(FMResultSet*)rs
{
    UserEntity *user = [[[UserEntity alloc] init] autorelease];
    user.ID = [rs intForColumn:
@"
_id
"];
    user.name = [rs stringForColumn:
@"
name
"];
    user.password = [rs  stringForColumn:
@"
password
"];
    
return user;
}
- (
void)addUser:(UserEntity *)user
{
    [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        [db open];
        NSString *sql = 
@"
insert into tbl_user(name, password) values (?, ?)
";
        [db executeUpdate:sql,user.name, user.password];
        [db close];
    }];  
}
- (NSArray *)getUsers;
{
    __block NSMutableArray *users = [[[NSMutableArray alloc] init] autorelease];  
    [self.dbQueue inDatabase:^(FMDatabase *db)   {
        [db open];
        NSString *sql = 
@"
select * from tbl_user 
";
        FMResultSet *rs = [db executeQuery:sql];
        
while ([rs next])
        {
            [users addObject:[self rsToUser :rs]]; 
        }
        [db close];
    }];
    
return users;
}

@end 

 

4. 编写测试方法

在didFinishLaunchingWithOptions 方法里启动3个线程 :2个线程写,1个线程读

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    
//
 Override point for customization after application launch.
    self.viewController = [[[ViewController alloc] initWithNibName:
@"
ViewController
" bundle:nil] autorelease];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    
    
    [NSThread detachNewThreadSelector:@selector(writeDbOne) toTarget:self withObject:nil];
    
    [NSThread detachNewThreadSelector:@selector(readDb) toTarget:self withObject:nil];
    
    [NSThread detachNewThreadSelector:@selector(writeDbTwo) toTarget:self withObject:nil];
    
    
return YES;
}

 

- (
void)writeDbOne
{
    DbDao *dao = [DbDao  sharedInstance];
    
for (
int i = 
0; i < 
500; i++)
    {
        @autoreleasepool 
        {
             UserEntity *user = [[[UserEntity alloc] init] autorelease];
             user.name = [NSString stringWithFormat:
@"
name %d
", i];
             user.password = [NSString stringWithFormat:
@"
password %d
", i];
             [dao addUser:user];
             NSLog(
@"
writeDbOne %d 
", i);
        }
       
    }
}
- (
void)writeDbTwo
{
    DbDao *dao = [DbDao  sharedInstance];
    
for (
int i = 
600; i < 
1200; i++)
    {
        @autoreleasepool 
        {
            UserEntity *user = [[[UserEntity alloc] init] autorelease];
            user.name = [NSString stringWithFormat:
@"
name %d
", i];
            user.password = [NSString stringWithFormat:
@"
password %d
", i];
            [dao addUser:user];
            NSLog(
@"
writeDbTwo %d 
", i);
        }
        
    }
}
- (
void)readDb
{
     DbDao *dao = [DbDao  sharedInstance];
     NSArray *users =   [dao getUsers];
     NSLog(
@"
%@
", users);

 

最后查看数据库信息,数据成功插入

 

 

 

结论 :使用新的FMDB ,很好的解决了多线程问题。 

 

 

 

团结就是力量,ios开发者自己的推广联盟 QQ群173063969  

 

转载地址:http://xlfvx.baihongyu.com/

你可能感兴趣的文章
Maven学习 (一) 搭建Maven环境
查看>>
【转】产品整合比创造更重要
查看>>
linux之fork()函数详解
查看>>
【持续更新】总结:C++开发时积累的一些零碎的东西
查看>>
mysql 正则
查看>>
最精简 代理代码
查看>>
response.setHeader()的用法
查看>>
WCF第一个Demo
查看>>
hdu 5053 the Sum of Cube(上海网络赛)
查看>>
Analyzer中进行货币转换
查看>>
2014年年终总结
查看>>
bat产生随机数并复制文件及生成文件列表
查看>>
【VLC-Android】vlc-android简例
查看>>
动态规划0—1背包问题
查看>>
List,Set,Map
查看>>
分享50款 Android 移动应用程序图标【下篇】
查看>>
RAID5和RAID10,哪种RAID更适合你(上)
查看>>
Reapp - 下一代的 Hybrid App 开发框架
查看>>
【BZOJ】1086: [SCOI2005]王室联邦
查看>>
tomcat启用压缩的方式
查看>>