多線程操做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

喜歡的打顆星

參考文章和項目 

得找找了,參考了好幾我的的代碼

相關文章
相關標籤/搜索