什么是FMDB
官方介绍:
This is an Objective-C wrapper around SQLite.
FMDB是针对libsqlite3框架进行封装的三方数据库,它以OC的方式封装了SQLite的C语言的API,使用步骤与SQLite相似。 FMDB的GitHub链接 ?
FMDB的优缺点
FMDB的基本类
FMDatabaseQueue : 用于在多线程中执行多个查询或更新的操作,它是线程安全的FMDatabase : 代表一个单独的SQLite数据库,用于执行SQL语句FMResultSet : 代表使用FMDatabase执行查询语句获得的结果
FMDB的使用方法
1.导入FMDB
- 使用Cocopads
pod 'FMDB' 引入FMDB,或在git上下载添加到项目中。 - 在项目中添加头文件:
#import "FMDB.h" 。 ?
2.创建FMDB数据库
(1)获取数据库文件的路径
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSString *sqlFilePath = [path stringByAppendingPathComponent:@"story.sqlite"];
?
- 关于
NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde) :
函数原型:NSArray<NSString *> *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
iPhone会为每一个应用程序生成一个私有目录,并随即生成一个数字字母串作为目录名。在每一次应用程序启动时,这个字母数字串都是不同于上一次。 iOS中沙盒模型中有四个文件夹,我们通常使用其中的Documents目录进行数据持久化的保存,而这个Documents目录可以通过:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserdomainMask,YES) 得到。
根据一个数据库文件路径来创建一个FMDatabase对象,路径三种形式:
一个文件的系统路径 :如果不存在该路径,会自动创建一个空字符串@"" :在一个临时目录下创建一个空的数据库,当数据库连接关闭,自动删除数据库文件NULL :会创建一个内存中临时数据库,当数据库连接关闭的时候,将被自动删除
后两种不是我们的需要,因为我们需要在关闭连接之后,数据库文件依旧存在。
(2)获取数据库
FMDatabase *db = [FMDatabase databaseWithPath:sqlFilePath];
self.DataBase = db;
(3)打开数据库
if (![self.Database open]) {
self.Database = nil;
return;
}
if ([self.Database open]) {
}
如果打开失败,则将db对象置位nil,直接return。因为既然都打不开,肯定不能进一步进行增删改查的操作。
(4)创表
BOOL result = [self.Database executeUpdate:@"CREATE TABLE 'collect_story' ('title' VARCHAR(255), 'image' BLOB)"];
if (result) {
NSLog(@"创表成功");
} else {
NSLog(@"创表失败");
}
(5)完整创建数据库
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSString *sqlFilePath = [path stringByAppendingPathComponent:@"story.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:sqlFilePath];
self.DataBase = db;
self
if (![self.Database open]) {
self.Database = nil;
return;
}
if ([self.Database open]) {
BOOL result = [self.Database executeUpdate:@"CREATE TABLE 'collect_story' ('title' VARCHAR(255), 'image' BLOB)"];
if (result) {
NSLog(@"创表成功");
} else {
NSLog(@"创表失败");
}
}
?
3.FMDB数据库的增删改查
增加数据
- (void)insertTitle:(NSString *)titleStr andImage:(NSDate *)imageDate {
if ([self.Database open]) {
NSLog(@"打开成功");
NSString *sql = @"INSERT INTO collect_story (title,image) VALUES (?,?)";
BOOL result = [self.Database executeUpdate:sql, titleStr, imageDate];
if (result) {
NSLog(@"增加数据成功");
} else {
NSLog(@"增加数据失败");
}
[self.Database close];
} else {
NSLog(@"打开失败");
}
}
第四行INSERT INTO XXX :向XXX数据库中插入数据。后边的第一个括号是你要赋值的索引,VALUES之后就是你要赋的值。注意索引和索引数的对应,还有要和当时定义类型的匹配。
删除数据
- (void)deleteData {
if ([self.Database open]) {
NSString *sql = @"delete from collect_story WHERE collectionState = ?";
BOOL result = [self.Database executeUpdate:sql, @"xixixixi"];
if (!result) {
NSLog(@"数据删除失败");
} else {
NSLog(@"数据删除成功");
}
[self.Database close];
}
}
第三行delete from XXX WHERE a = ? :意思是删除XXX数据库中的一组数据,当WHERE之后的a = ?条件成立后。
更新数据
- (void)updateData {
if ([self.Database open]) {
NSString *sql = @"UPDATE collect_story SET id = ? WHERE nameLabel = ?";
BOOL result = [self.Database executeUpdate:sql, @"111", @"复杂化"];
if (!result) {
NSLog(@"数据修改失败");
} else {
NSLog(@"数据修改成功");
}
[self.Database close];
}
}
第三行UPDATE XXX SET id = ? WHERE a = ? :意思是更新XXX中的id索引对应的数据,当WHERE后的 a = ? 条件成立的时候。
查找数据
- (void)queryData {
if ([self.Database open]) {
FMResultSet *resultSet = [self.Database executeQuery:@"SELECT * FROM collect_story"];
while ([resultSet next]) {
NSString *nameLabel = [resultSet stringForColumn:@"nameLabel"];
NSLog(@"nameLabel = %@",nameLabel);
NSString *imageURL = [resultSet stringForColumn:@"imageURL"];
NSLog(@"imageURL = %@",imageURL);
}
[self.Database close];
}
}
第三行SELECT * FROM XXX :选择XXX中的数据。
上述代码都是基本的增删改查语句,还有更高级的SQL语句,能提供更丰富的操作。SQL常用增删改查语句 ?
FMDB相关
1.FMDB使用须知
- 多线程不能共享一个FMDatabase对象,也不能在多线程下同时创建多个FMDatabaseQueue实例来操作同一个数据库,这样可能会造成数据的操作丢失。
- FMDB是sqlite的封装,而文件数据sqlite在同一时刻允许多个线程、进程读,但是同一时刻不允许多个线程写。
- FMDatabaseQueue解决多线程问题的思路:创建一个队列,然后将需要执行的数据库操作放到block中。队列中的block按照添加进队列的顺序依次执行,实际上还是同步的操作,避免了多个线程对数据库的访问。
2.数据库存储的数据类型
- integer:整形值
- real:浮点值
- text:文本字符串
- blob:二进制数据(比如文件)
?
未完待续
- 不同数据库是否使用“事物”方式插入数据效率不同
数据库事务的概念及其实现原理
- 关于FMDatabaseQueue的线程安全FMDatabaseQueue 如何保证线程安全
|