sqliteIOS多线程读写Sqlite问题化解

而今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);

 

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

 sqlite 1

 

 

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

 

 品种文件下充斥

 

合力就是是能力,ios开发者自己之推广联盟
QQ群
173063969 ** 

 

网站地图xml地图