多线程操做FMDB的实践

最近在弄项目的时候,须要多线程读写数据库,以前用的SQlite遇到多线程就不给力,很容易出现ACCESS_BAD的问题,因而找了些资料,发现FMDB的FMDBQueue能够比较容易的处理多线程的问题,因此就写了个demoios

 

 

1,首先导入FMDB框架,能够采用cocoapods 管理依赖git

对应的Podfile以下github

platform :ios, '7.0'

pod 'AFNetworking', '~> 2.0'

pod 'FMDB', '~>2.2'

pod 'Masonry','~>0.6'

 

本身下载而后导入FMDB模块也是能够的sql

 

 

2,操做的学生类Student类有3个属性,学生ID,学生姓名和年龄。数据库


 

#import <Foundation/Foundation.h>



@interface Student : NSObject



@property (nonatomic,copy) NSString *studentID;



@property (nonatomic,copy) NSString *studentName;



@property (nonatomic,strong) NSNumber *studentAge;



@end

 

3,建立GJFMDBQueueHelper的单例多线程

 

- (id)init

{



    static id obj=nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken,^{

        if ((obj =[super init])!=nil) {

            //建立表

            [self createDatabaseTable];



        }



    });

    self=obj;



    return  self;

}



+ (id)allocWithZone:(struct _NSZone *)zone

{

    // 里面的代码永远只执行1次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedHelper = [super allocWithZone:zone];

    });



    // 返回对象

    return sharedHelper;

}



+ (instancetype)sharedHelper

{

    // 里面的代码永远只执行1次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedHelper = [[self alloc] init];

    });



    // 返回对象

    return sharedHelper;

}



+ (id)copyWithZone:(struct _NSZone *)zone

{

    return sharedHelper;

}

 

 

4,建立表框架

-(BOOL)createDatabaseTable

{



    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite",databaseName]];



    self.dbQueue = [FMDatabaseQueue databaseQueueWithPath:filePath];

    [self.dbQueue inDatabase:^(FMDatabase *db) {





        NSString *sql = @"CREATE TABLE IF NOT EXISTS t_students (student_id integer PRIMARY KEY AUTOINCREMENT,student_age integer NOT NULL,student_name text NOT NULL );";

        BOOL result= [db executeUpdate:sql];

        NSLog(@"%@",result?@"create table t_students success":@"create table t_students faiiled");





    }];

    return YES;

}

 

5实现数据库的增删改查方法dom

async

/*add */

-(BOOL)addNewStudentToDB:(Student *)student{



    __block BOOL insertResult=NO;

    [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {



        [db open];

        NSString *sqlString=[NSString stringWithFormat:@"INSERT INTO t_students (student_name,student_age) VALUES ('%@',%ld)",

                             student.studentName,

                             [student.studentAge integerValue]];

        insertResult=[db executeUpdate:sqlString];

        [db close];



    }];



    return insertResult;





}

 

测试

/* delete */

-(BOOL)deleteStudentByStudentID:(NSString *)studentID{

    __block BOOL result=NO;

    [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {

        [db open];

        NSString *sqlString=[NSString stringWithFormat:@"DELETE FROM t_students WHERE student_id = %ld",[studentID integerValue]];

        result=[db executeUpdate:sqlString];

        [db close];

    }];



    return result;





}

 

/*update*/

-(BOOL)updateWithSQL:(NSString *)sqlString{



    NSLog(@"update sql==%@",sqlString);



    __block BOOL  updateResult=NO;





    [self.dbQueue inDatabase:^(FMDatabase *db)   {

        [db open];

        updateResult=[db executeUpdate:sqlString];

        [db close];



    }];



    return updateResult;



}

 

 

 

 

/*query */

-(NSArray *)modelsWithSQL:(NSString *)sqlString{

    __block NSMutableArray *eventModels=[NSMutableArray array];



    NSLog(@"query sql==%@",sqlString);

    [self.dbQueue inDatabase:^(FMDatabase *db)   {

        [db open];



        FMResultSet *rs = [db executeQuery:sqlString];

        while ([rs next])

        {

            //

            [eventModels addObject:[self modelFromRS :rs]];

        }

        [db close];

    }];

    return eventModels;



}


 

 

外部调用

 

 

在程序启动的时候判断是否有记录,若是没有的话,加入100条随机的数据 

GJFMDBQueueHelper *fmdbHelper=[GJFMDBQueueHelper sharedHelper];

    NSArray *students=[fmdbHelper allStudents];

    if (students.count==0) {
        NSArray *nameArray=@[@"Jim",@"Mike",@"Lucy",@"Jessica"];
        for (int i=0; i<100; i++) {

            Student *student=[[Student alloc]init];
            student.studentName=nameArray[i%(nameArray.count-1)];
            student.studentAge=@(arc4random()%60+10);
            [fmdbHelper addNewStudentToDB:student];

        }
    }

 

 


  多线程测试

 

-(void)pressMTOButton{

    NSLog(@"test mutiple thread operation");



    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //read



        GJFMDBQueueHelper *fmdbHelper=[GJFMDBQueueHelper sharedHelper];

        for (int i=0; i<100; i++) {

            Student *student=    [fmdbHelper studentWithStudentID:[NSString stringWithFormat:@"%d",i]];

            NSLog(@"111 first dispatch  studnet==%@",student);





        }



    });



    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //write



        GJFMDBQueueHelper *fmdbHelper=[GJFMDBQueueHelper sharedHelper];



        for (int i=0; i<100; i++) {

            Student *student=[[Student alloc]init];

            student.studentName=@"StudentDemo";

            student.studentAge=@11;

            NSLog(@"222 second dispatch operation ==%@",student);



            [fmdbHelper addNewStudentToDB:student];

        }



    });



    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //delete



        GJFMDBQueueHelper *fmdbHelper=[GJFMDBQueueHelper sharedHelper];

        for(int i=0;i<100;i++){



            NSArray *students=[fmdbHelper studentsWithStudentName:@"StudentDemo"];

            Student *student=students.firstObject;

            if (student) {

                [fmdbHelper deleteStudentByStudentID:student.studentID];

                NSLog(@"333 third dispatch operation %@",student);

            }



        }

    });



}

 

 

完整项目代码请在github中查看

https://github.com/knight314/FMDBStudentsDemo

喜欢的打颗星

参考文章和项目 

得找找了,参考了好几我的的代码

相关文章
相关标签/搜索