SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全

(1)下载地址:https://github.com/ccgus/fmdbgit

 

(2)注意点github

——语句能够带分号“;”,也能够省略分号。sql

——一样须要添加“libsqlite3.dylib”库才能使用。数据库

——移动端的开发中,通常不关闭数据库,即不怎么使用[self.db close];,由于每次从新打开比较耗性能,且每次程序关闭时数据库天然会同时关闭。安全

 

(3)用法dom

 

#import "ViewController.h"
#import "FMDB.h"

@interface ViewController ()
@property(nonatomic,strong) FMDatabase *db;
- (IBAction)insert:(id)sender;
- (IBAction)delete:(id)sender;
- (IBAction)update:(id)sender;
- (IBAction)select:(id)sender;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *filePath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"fmdb.sqlite"];
    //建立数据库
    self.db=[FMDatabase databaseWithPath:filePath];
    //打开数据库
    if ([self.db open]) {
        NSLog(@"打开数据库成功");
        //建立表格,除了select外,全部的操做都是更新
        BOOL createTableResult=[self.db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer)"];
        if (createTableResult) {
            NSLog(@"建立表成功");
        }else{
            NSLog(@"建立表失败");
        }
    }else{
        NSLog(@"打开数据库失败");
    }
}

- (IBAction)insert:(id)sender {
    for (int index=0; index<50; index++) {
        NSString *s_name=[NSString stringWithFormat:@"Andy%d",arc4random()%100];
        NSNumber *s_age=@(arc4random()%100);
        [self.db executeUpdate:@"INSERT INTO t_student(name,age) VALUES(?,?)",s_name,s_age];
    }
}

- (IBAction)delete:(id)sender {
    [self.db executeUpdate:@"DELETE FROM t_student WHERE id=?",@1];
}

- (IBAction)update:(id)sender {
    [self.db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
}

- (IBAction)select:(id)sender {
    //获取结果集,返回参数就是查询结果
    FMResultSet *rs=[self.db executeQuery:@"SELECT * FROM t_student WHERE age>?",@50];
    while ([rs next]) {
        int ID=[rs intForColumn:@"id"];
        NSString *NAME=[rs stringForColumn:@"name"];
        int AGE=[rs intForColumn:@"age"];
        NSLog(@"%d %@ %d",ID,NAME,AGE);
    }
}
@end


(4)使用FMDatabaseQueue保证线程安全(建议之后都这么作)性能

 

——主要就是在建立数据库的时候,默认已经打开数据库atom

——随后的不少操做,由于须要在数据库中操做,因此须要利用队列的inDataBase方法调出数据库,在block中执行操做代码。线程

 

#import "ViewController.h"
#import "FMDB.h"

@interface ViewController ()
@property(nonatomic,strong) FMDatabaseQueue *queue;
- (IBAction)insert:(id)sender;
- (IBAction)delete:(id)sender;
- (IBAction)update:(id)sender;
- (IBAction)select:(id)sender;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *filePath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"fmdb.sqlite"];
    //建立数据库,并加入到队列中,此时已经默认打开了数据库,无须手动打开,只须要从队列中去除数据库便可
    self.queue=[FMDatabaseQueue databaseQueueWithPath:filePath];
    //取出数据库,这里的db就是数据库,在数据库中建立表
    [self.queue inDatabase:^(FMDatabase *db) {
        //建立表
        BOOL createTableResult=[db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer)"];
        if (createTableResult) {
            NSLog(@"建立表成功");
        }else{
            NSLog(@"建立表失败");
        }
    }];
}

- (IBAction)insert:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        for (int index=0; index<50; index++) {
            NSString *s_name=[NSString stringWithFormat:@"Andy%d",arc4random()%100];
            NSNumber *s_age=@(arc4random()%100);
            [db executeUpdate:@"INSERT INTO t_student(name,age) VALUES(?,?)",s_name,s_age];
        }
    }];
}

- (IBAction)delete:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:@"DELETE FROM t_student WHERE id=?",@1];
    }];
}

- (IBAction)update:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
    }];
}

- (IBAction)select:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        //获取结果集,返回参数就是查询结果
        FMResultSet *rs=[db executeQuery:@"SELECT * FROM t_student WHERE age>?",@50];
        while ([rs next]) {
            int ID=[rs intForColumn:@"id"];
            NSString *NAME=[rs stringForColumn:@"name"];
            int AGE=[rs intForColumn:@"age"];
            NSLog(@"%d %@ %d",ID,NAME,AGE);
        }
    }];
}


(5)若是要保证多个操做同时成功或者同时失败,用事务,即把多个操做放在同一个事务中。orm

 

——FMDB中,拿到数据库直接操做事务,以下:

 

- (IBAction)update:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        [db beginTransaction];
        [db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
        [db executeUpdate:@"UPDATE t_student SET name='Tomy' WHERE id=?",@3];
        //发现状况不对时,主动回滚用下面语句。不然是根据commit结果,如成功就成功,如不成功才回滚
        [db rollback];
        [db executeUpdate:@"UPDATE t_student SET name='Eric' WHERE id=?",@4];
        [db commit];
    }];
}


上面由于用的是FMDB封装好的,其实原生的代码是这样的:

 

 

[db executeUpdate:@"BEGIN TRANSACTION"];
[db executeUpdate:@"ROLLBACK TRANSACTION"];
[db executeUpdate:@"COMMIT TRANSACTION"];

 

 

——FMDB中,也能够直接利用队列进行事务操做,队列中的打开、关闭、回滚事务等都已经被封装好了。

 

- (IBAction)update:(id)sender {
    [self.queue inDatabase:^(FMDatabase *db) {
        [self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            [db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
            [db executeUpdate:@"UPDATE t_student SET name='Tomy' WHERE id=?",@3];
            //发现状况不对时,主动回滚用下面语句。
            *rollback=YES;
            [db executeUpdate:@"UPDATE t_student SET name='Eric' WHERE id=?",@4];
        }];
}
相关文章
相关标签/搜索