【iOS开发-105】SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全

前端之家收集整理的这篇文章主要介绍了【iOS开发-105】SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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


(2)注意点

——语句可以带分号“;”,也可以省略分号。

——同样需要添加“libsqlite3.dylib”库才能使用。

——移动端的开发中,一般不关闭数据库,即不怎么使用[self.db close];,因为每次重新打开比较耗性能,且每次程序关闭数据库自然会同时关闭


(3)用法

  1. #import "ViewController.h"
  2. #import "FMDB.h"
  3.  
  4. @interface ViewController ()
  5. @property(nonatomic,strong) FMDatabase *db;
  6. - (IBAction)insert:(id)sender;
  7. - (IBAction)delete:(id)sender;
  8. - (IBAction)update:(id)sender;
  9. - (IBAction)select:(id)sender;
  10. @end
  11.  
  12. @implementation ViewController
  13.  
  14. - (void)viewDidLoad {
  15. [super viewDidLoad];
  16. NSString *filePath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent:@"fmdb.sqlite"];
  17. //创建数据库
  18. self.db=[FMDatabase databaseWithPath:filePath];
  19. //打开数据库
  20. if ([self.db open]) {
  21. NSLog(@"打开数据库成功");
  22. //创建表格,除了select外,所有的操作都是更新
  23. BOOL createTableResult=[self.db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer)"];
  24. if (createTableResult) {
  25. NSLog(@"创建表成功");
  26. }else{
  27. NSLog(@"创建表失败");
  28. }
  29. }else{
  30. NSLog(@"打开数据库失败");
  31. }
  32. }
  33.  
  34. - (IBAction)insert:(id)sender {
  35. for (int index=0; index<50; index++) {
  36. NSString *s_name=[NSString stringWithFormat:@"Andy%d",arc4random()%100];
  37. NSNumber *s_age=@(arc4random()%100);
  38. [self.db executeUpdate:@"INSERT INTO t_student(name,age) VALUES(?,?)",s_name,s_age];
  39. }
  40. }
  41.  
  42. - (IBAction)delete:(id)sender {
  43. [self.db executeUpdate:@"DELETE FROM t_student WHERE id=?",@1];
  44. }
  45.  
  46. - (IBAction)update:(id)sender {
  47. [self.db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
  48. }
  49.  
  50. - (IBAction)select:(id)sender {
  51. //获取结果集,返回参数就是查询结果
  52. FMResultSet *rs=[self.db executeQuery:@"SELECT * FROM t_student WHERE age>?",@50];
  53. while ([rs next]) {
  54. int ID=[rs intForColumn:@"id"];
  55. NSString *NAME=[rs stringForColumn:@"name"];
  56. int AGE=[rs intForColumn:@"age"];
  57. NSLog(@"%d %@ %d",ID,NAME,AGE);
  58. }
  59. }
  60. @end

(4)使用FMDatabaseQueue保证线程安全(建议以后都这么做)

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

——随后的很多操作,因为需要在数据库中操作,所以需要利用队列的inDataBase方法调出数据库,在block中执行操作代码

  1. #import "ViewController.h"
  2. #import "FMDB.h"
  3.  
  4. @interface ViewController ()
  5. @property(nonatomic,strong) FMDatabaseQueue *queue;
  6. - (IBAction)insert:(id)sender;
  7. - (IBAction)delete:(id)sender;
  8. - (IBAction)update:(id)sender;
  9. - (IBAction)select:(id)sender;
  10. @end
  11.  
  12. @implementation ViewController
  13.  
  14. - (void)viewDidLoad {
  15. [super viewDidLoad];
  16. NSString *filePath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,YES) lastObject] stringByAppendingPathComponent:@"fmdb.sqlite"];
  17. //创建数据库,并加入到队列中,此时已经默认打开了数据库,无须手动打开,只需要从队列中去除数据库即可
  18. self.queue=[FMDatabaseQueue databaseQueueWithPath:filePath];
  19. //取出数据库,这里的db就是数据库,在数据库中创建表
  20. [self.queue inDatabase:^(FMDatabase *db) {
  21. //创建表
  22. BOOL createTableResult=[db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT,age integer)"];
  23. if (createTableResult) {
  24. NSLog(@"创建表成功");
  25. }else{
  26. NSLog(@"创建表失败");
  27. }
  28. }];
  29. }
  30.  
  31. - (IBAction)insert:(id)sender {
  32. [self.queue inDatabase:^(FMDatabase *db) {
  33. for (int index=0; index<50; index++) {
  34. NSString *s_name=[NSString stringWithFormat:@"Andy%d",arc4random()%100];
  35. NSNumber *s_age=@(arc4random()%100);
  36. [db executeUpdate:@"INSERT INTO t_student(name,s_age];
  37. }
  38. }];
  39. }
  40.  
  41. - (IBAction)delete:(id)sender {
  42. [self.queue inDatabase:^(FMDatabase *db) {
  43. [db executeUpdate:@"DELETE FROM t_student WHERE id=?",@1];
  44. }];
  45. }
  46.  
  47. - (IBAction)update:(id)sender {
  48. [self.queue inDatabase:^(FMDatabase *db) {
  49. [db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
  50. }];
  51. }
  52.  
  53. - (IBAction)select:(id)sender {
  54. [self.queue inDatabase:^(FMDatabase *db) {
  55. //获取结果集,返回参数就是查询结果
  56. FMResultSet *rs=[db executeQuery:@"SELECT * FROM t_student WHERE age>?",@50];
  57. while ([rs next]) {
  58. int ID=[rs intForColumn:@"id"];
  59. NSString *NAME=[rs stringForColumn:@"name"];
  60. int AGE=[rs intForColumn:@"age"];
  61. NSLog(@"%d %@ %d",AGE);
  62. }
  63. }];
  64. }

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

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

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

上面因为用的是FMDB封装好的,其实原生的代码是这样的:
  1. [db executeUpdate:@"BEGIN TRANSACTION"];
  2. [db executeUpdate:@"ROLLBACK TRANSACTION"];
  3. [db executeUpdate:@"COMMIT TRANSACTION"];

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

  1. - (IBAction)update:(id)sender {
  2. [self.queue inDatabase:^(FMDatabase *db) {
  3. [self.queue inTransaction:^(FMDatabase *db,BOOL *rollback) {
  4. [db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];
  5. [db executeUpdate:@"UPDATE t_student SET name='Tomy' WHERE id=?",@3];
  6. //发现情况不对时,主动回滚用下面语句。
  7. *rollback=YES;
  8. [db executeUpdate:@"UPDATE t_student SET name='Eric' WHERE id=?",@4];
  9. }];
  10. }

猜你在找的Sqlite相关文章