1.前言
iOS中原生的SQLite
API在进行数据存储的时候,需要使用C语言中的函数,操作比较麻烦。于是,就出现了一系列将SQLite API进行封装的库,例如FMDB
、PlausibleDatabase
、sqlitepersistentobjects
等。
2.FMDB
FMDB是一款简洁、易用的封装库。因此,在这里推荐使用第三方框架FMDB,它是对libsqlite3框架的封装,用起来的步骤与SQLite使用类似,并且它对于多线程的并发操作进行了处理,所以是线程安全的。
优点:
- 线程安全,对多线程的并发操作进行处理;
- 以OC的方式封装了
SQLite
的C语言API,使用起来更加的方便; - FMDB是轻量级的框架,使用灵活。
缺点:
- 是OC的语言封装的,只能在ios开发的时候使用,所以在实现跨平台操作的时候存在局限性。
- 多张表与表之间产生属性关联,用FMDB会比较麻烦
3.FMDB构成
- FMDatabase : FMDatabase对象就是一个数据库,单线程
- FMDatabaseQueue : 多线程
- FMResultSet : 查询的结果集
4 集成
- 下载FMDB,并将fmdb文件夹导入到工程中
- 导入需要的框架:libsqlite3.0
5 增删改查
创建一个类:
#import "NCModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface People : NCModel
@property(nonatomic)int id;
@property(nonatomic)int age;
@property(nonatomic,strong)NSString *name;
@property(nonatomic,strong)NSString *sex;
@end
创建一个数据库
+ (NSString *)obtainBasePath{
return [NSTemporaryDirectory() stringByAppendingPathComponent:@"nicolas.db"];
}
+ (FMDatabase *)openDatabase{
//1 创建路径
NSString *path = [HandleFMDBModel obtainBasePath];
//2 创建数据库
FMDatabase *db = [FMDatabase databaseWithPath:path];
//3 是否可以打开
if ([db open]) {
//4.创表
BOOL result = [db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_people (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL,sex text, age integer NOT NULL);"];
if (result)
{
NSLog(@"创建表成功");
}
}
return db;
}
插入数据,有三种方式,返回成功与否
__block bool suc = false;
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[HandleFMDBModel obtainBasePath]];
[queue inDatabase:^(FMDatabase * _Nonnull db) {
//1.executeUpdate:不确定的参数用?来占位(后面参数必须是oc对象,;代表语句结束)
NSString *sql = @"INSERT INTO t_people (id, name, age) VALUES (?,?,?);";
suc = [db executeUpdate:sql,@(Id),name,@(age)];
// //2.executeUpdateWithForamat:不确定的参数用%@,%d等来占位 (参数为原始数据类型,执行语句不区分大小写)
// suc = [db executeUpdateWithFormat:@"insert into t_people (id,name,age) values (%i,%@,%i);",Id,name,age];
//
// //3.参数是数组的使用方式
// suc = [db executeUpdate:@"INSERT INTO t_people(id,name,age) VALUES (?,?,?);"withArgumentsInArray:@[@(Id),name,@(age)]];
}];
return suc;
删除数据
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[HandleFMDBModel obtainBasePath]];
[queue inDatabase:^(FMDatabase * _Nonnull db) {
//1.不确定的参数用?来占位 (后面参数必须是oc对象,需要将int包装成OC对象)
[db executeUpdate:@"delete from t_people where id = ?;",@(id)];
//2.不确定的参数用%@,%d等来占位
[db executeUpdateWithFormat:@"delete from t_people where name = %@;",@"nicolas"];
}];
修改数据
__block bool suc = false;
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[HandleFMDBModel obtainBasePath]];
[queue inDatabase:^(FMDatabase * _Nonnull db) {
suc = [db executeUpdate:@"update t_people set name = ? where name = ?",newName,name];
}];
return suc;
查询数据,需要熟悉相关的数据库知识
//查询整个表
FMResultSet *resultSet = [db executeQuery:@"select * from t_people;"];
//根据条件查询
FMResultSet *resultSet2 = [db executeQuery:@"select * from t_people where id<?;",@(14)];
打印结果
FMResultSet *resultSet = [HandleFMDBModel executeDataBase];
NSInteger column = resultSet.columnCount;
while ([resultSet next])
{
int idNum = [resultSet intForColumn:@"id"];
NSString *name = [resultSet
objectForColumn:@"name"];
int age = [resultSet intForColumn:@"age"];
NSLog(@"==%ld==id:%d name:%@ age:%d",idex,idNum,name,age);
}
注:在多个线程中同时使用一个FMDatabase实例是不明智的。现在你可以为每 个线程创建一个FMDatabase对象,不要让多个线程分享同一个实例,他无 法在多个线程中同事使用。否则程序会时不时崩溃或者报告异常。所以,不要 初始化FMDatabase对象,然后在多个线程中使用。这时候,我们就需要使 用FMDatabaseQueue来创建队列执行事务。
我封装了一个小demo有需要的可以自行下载
6 本地查看数据
真机下,先导出.db文件,然后用SQLiteManager进行查看。
或者在线查看
写的有些仓促,文章和代码若有不对地方,欢迎批评指正。
网友评论