iOS之FMDB的基本使用
来源:互联网 发布:网络教育考试时间 编辑:程序博客网 时间:2024/06/05 15:15
- 优点 :
- 对多线程的并发操作进行处理,所以是线程安全的
- 以OC的方式封装了SQLite的C语言API,使用起来更加的方便;
- FMDB是轻量级的框架,使用灵活
- 缺点:
- 因为它是OC的语言封装的,只能在iOS开发的时候使用, 所以在实现跨平台操作的时候存在局限性
FMDB中重要的类
- FMDatabase : 一个FMDatabase对象就代表一个单独的SQLite数据库, 用来执行SQL语句
- FMResultSet : 使用FMDatabase执行查询的结果集
- FMDatabaseQueue : 用于在多线程中执行多个查询或更新,它是线程安全的
FMDB数据库(SQLite)下的使用 :
注意: 创建FMDatabase对象时参数为SQLite数据库文件路径, 该路径可以是一下三种方式之一- 文件路径.该文件路径无需真是存在,如果不存在会自动创建- 空字符串(@“”). 表示会在临时目录创建一个空的数据库,当FMDatabase连接关闭时,文件也会被删除- NULL. 将创建一个内在数据库, 同样的, 当FMDatabase连接关闭时, 数据将会被摧毁 首先要导入libsqlite3.0框架,导入头文件 import <FMDB/FMDB.h> 代码实现: (对FMDB中数据库的增删改查的简单封装)
#import "FMDBHelp.h"#import <FMDB/FMDB.h>@interface FMDBHelp ()@property(nonatomic,strong)NSString *fileName;//数据库文件的路径@property(nonatomic,strong)FMDatabase *database; //数据库对象@end@implementation FMDBHelp#pragma mark - 单例+ (FMDBHelp*)sharedFMDBHelp { static FMDBHelp *help = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ help = [[FMDBHelp alloc] init]; }); return help;}#pragma mark - 让用户来命名数据库的名称- (void)createDBWithName:(NSString*)dbName { if (dbName.length == 0) { //是防止用户直接传值为nil 或者 NULL self.fileName = @""; } else { //判断用户是否为数据库文件添加后缀名 if ([dbName containsString:@".sqlite"]) { self.fileName = dbName; } else { self.fileName = [dbName stringByAppendingString:@".sqlite"]; } }}#pragma amrk - 根据名称创建沙盒路径用来保存数据库文件- (NSString*)dbPath { //说明fileName不为空 if (self.fileName.length) { //获取沙盒主路径 NSString *homePath = NSHomeDirectory(); //完整路径 NSString *savePath = [homePath stringByAppendingPathComponent:[NSString stringWithFormat:@"documents/%@",self.fileName]]; NSLog(@"%@",savePath); return savePath; } else { return @""; }}#pragma mark - 创建数据库对象//懒加载- (FMDatabase*)database { if (!_database) { _database = [FMDatabase databaseWithPath:[self dbPath]]; } return _database;}#pragma mark - 打开或者创建数据库- (BOOL)openOrCreateDB { if ([self.database open]) { NSLog(@"数据库打开成功"); return YES; } else { NSLog(@"数据库打开失败"); return NO; }}#pragma mark - 无返回结果集的操作- (BOOL)notResultSetWithSql:(NSString*)sql { //打开数据库 BOOL isOpen = [self openOrCreateDB]; if (isOpen) { //进行操作 BOOL isSuccess = [self.database executeUpdate:sql]; [self closeDB]; NSLog(@"打开数据库成功"); return isSuccess; } else { NSLog(@"打开数据库失败"); return NO; }}#pragma mark - 关闭数据库的方法- (void)closeDB { BOOL isClose = [self.database close]; if (isClose) { NSLog(@"关闭数据库成功"); } else { NSLog(@"关闭数据库失败"); }}#pragma mark - 通用的查询方法- (NSArray*)qureyWithSql:(NSString*)sql { //打开数据库 BOOL isOpen = [self openOrCreateDB]; if (isOpen) { //得到所有记录的结果集 FMResultSet *set = [self.database executeQuery:sql]; //声明一个可变数组,用来存放所有的记录 NSMutableArray *array = [NSMutableArray array]; //遍历结果集,取出每一条记录,将每一条记录转换为字典类型,并且存储到可变数组中 while ([set next]) { //直接将一条记录转换为字典类型 NSDictionary *dic = [set resultDictionary]; [array addObject:dic]; } //释放结果集 [set close]; [self closeDB]; return array; } else { NSLog(@"打开数据库失败"); return nil; }}
#import <Foundation/Foundation.h>@interface FMDBHelp : NSObject+ (FMDBHelp*)sharedFMDBHelp;//给数据库命名- (void)createDBWithName:(NSString*)dbName;//无返回结果集的操作- (BOOL)notResultSetWithSql:(NSString*)sql;//查询操作- (NSArray*)qureyWithSql:(NSString*)sql;@end
FMDB多线程下的使用
- 如果应用中使用了多线程操作数据库, 那么就需要使用FMDatabaseQueue来保证线程安全. 应用中不可再多个线程中公共使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱(例如,使用两个线程同时对数据库进行更新和查找). 为了多线程操作数据库安全, FMDB使用了FMDatabaseQueue.
- 多个线程更新相同的资源导致数据竞争时使用等待队列(等待现在执行的处理结束)
// 打开数据库 [self openDB];// 在子线程中执行数据库插入操作 dispatch_sync(dispatch_get_global_queue(0, 0), ^{ [self threadNoTransaction]; });#pragma mark - 数据存储文件的路径- (NSString *)dbPath { NSString *string = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *stringPath = [string stringByAppendingPathComponent:@"test.sqlite"]; NSLog(@"%@",stringPath); return stringPath;}#pragma mark - 打开数据库并建表- (void)openDB { FMDatabase *database = [FMDatabase databaseWithPath:[self dbPath]]; //打开数据库,如果数据库打开,建表,如果失败就返回错误信息 if([database open]) { //建表 BOOL isSuccess = [database executeUpdate:@"create table if not exists stu(name text)"]; if (isSuccess) { NSLog(@"建表成功"); } else { NSLog(@"建表失败"); } } else { NSLog(@"打开数据库失败"); }}#pragma mark - 多线程操作数据库时,非事务的处理方式// 事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行。所以,应该把它们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性- (void)threadNoTransaction { //数据库文件的路径 FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self dbPath]]; //将一组操作添加到非事务处理中 [queue inDatabase:^(FMDatabase *db) { //将操作放入事务中,加入事务操作 [db beginTransaction]; BOOL isError = NO; int temp = -1; for (int i = 0; i < 10000; i++) { isError = [db executeUpdate:@"insert into stu values(?)",@(i)]; if (!isError) {//说明inError == NO,插入有问题 if(temp == -1) { temp = i; } } } if (isError) { NSLog(@"所有插入动作成功"); } else { NSLog(@"所有插入动作失败---%d",temp); } //提交事务 [db commit]; }];}#pragma mark - 多线程操作数据库时,事务的处理方式- (void)threadTransaction { //创建队列 FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self dbPath]]; __block BOOL whoopsSomethingWrongHappened = true; //把任务包装到事务里 [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTable values(?)",[NSNumber numberWithInt:1]]; whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTable values(?)",[NSNumber numberWithInt:2]]; whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTable values(?)",[NSNumber numberWithInt:3]]; //如果有错误 返回 if(!whoopsSomethingWrongHappened) { *rollback = YES; return; } }];}
1 0
- iOS之FMDB的基本使用
- iOS 第三方框架之FMDB的基本使用
- iOS开发-FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- FMDB的基本使用
- iOS FMDB的使用
- iOS FMDB的使用
- Ios fmdb的使用
- iOS FMDB的使用
- ios数据库之fmdb 使用
- 关于FMDB的基本使用
- IOS中FMDB的使用
- IOS -- FMDB的使用心得
- C语言实现多态
- Cordova 6 常用插件
- 无线传感网络通信标准IEEE 802.15.4
- 使用php脚本向Mysql服务器发送SQL(基本)
- java学习总结
- iOS之FMDB的基本使用
- CentOS 7 上编译安装MySQL 5.6.29
- NGINX引入线程池 性能提升9倍
- 机器学习入门系列四(关键词:BP神经网络)
- 【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案
- 剑指offer之编程(八)
- 23.二叉树中和为某一值的路径(做第二遍时感觉仍有难度,第三次做还是要看一下思路)
- navicat 如何设置外键
- [bzoj3065]带插入区间K小值