前言
日常的项目中,我们经常涉及到数据持久化的问题,苹果给我们提供的出具持久化方案有属性列表(plist)、归档(NSKeyedArchiver
/NSUserDefaults
)、数据库(sqlite)和core。但是在实际的项目开发中,我们用的最多的是sqlite,而sqlite的操作我们一般都是使用FMDB,那么今天就简单的说一下在项目开发中的FMDB的简单使用。
创建 UserDetailModel
类(我们要持久化存储的数据模型),因为要使用到NSKeyedArchiver
,因此需要遵循NSCoding
协议。
#define kuserid_UserDetailModel @"userid_UserDetailModel"
#define kusernickname_UserDetailModel @"usernickname_UserDetailModel"
#define kage_UserDetailModel @"age_UserDetailModel"
#define kbirthday_UserDetailModel @"birthday_UserDetailModel"
#define ksex_UserDetailModel @"sex_UserDetailModel"
#import <Foundation/Foundation.h>
@interface UserDetailModel : NSObject<NSCoding>
//用户Id
@property (copy, nonatomic) NSString *userid;
//昵称
@property (copy, nonatomic) NSString *usernickname;
//年龄
@property (copy, nonatomic) NSString *age;
//生日
@property (copy, nonatomic) NSString *birthday;
//性别
@property (copy, nonatomic) NSString *sex;
@end
实现NSCoding的方法
#import "UserDetailModel.h"
#import "FYUser.h"
@implementation UserDetailModel
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:_userid forKey:kuserid_UserDetailModel];
[aCoder encodeObject:_usernickname forKey:kusernickname_UserDetailModel];
[aCoder encodeObject:_age forKey:kage_UserDetailModel];
[aCoder encodeObject:_birthday forKey:kbirthday_UserDetailModel];
[aCoder encodeObject:_sex forKey:ksex_UserDetailModel];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self = [super init]) {
_userid = [aDecoder decodeObjectForKey:kuserid_UserDetailModel];
_usernickname = [aDecoder decodeObjectForKey:kusernickname_UserDetailModel];
_age = [aDecoder decodeObjectForKey:kage_UserDetailModel];
_birthday = [aDecoder decodeObjectForKey:kbirthday_UserDetailModel];
_sex = [aDecoder decodeObjectForKey:ksex_UserDetailModel];
}
return self;
}
@end
创建一个DataBaseManager
单例,用来进行UserDetailModel
的数据库操作
#import <Foundation/Foundation.h>
#import "UserDetailModel.h"
/**
联系人的数据库操作
*/
@interface DataBaseManager : NSObject
/**
获取操作者
@return 操作者
*/
+ (instancetype)sharedManager;
#pragma mark - UserDetailOperate Methods
/**
插入或者更新用户信息
@param userDetail 登录的用户用户信息
@return 操作结果
*/
- (BOOL)updateUserDetail:(UserDetailModel *)userDetail;
/**
删除用户
@param userDetail 用户详细信息
@return 操作结果
*/
- (BOOL)deleteUserDetail:(UserDetailModel *)userDetail;
/**
获取用户详细信息
@param userid 用户id
@return 用户
*/
- (UserDetailModel *)getUserDetailByUserId:(NSString *)userid;
@end
实现DataBaseManager里相应的方法
#import "DataBaseManager.h"
#import <FMDB/FMDB.h>
@interface DataBaseManager()
//使用FMDatabaseQueue防止线程操作发生崩溃
@property (strong, nonatomic) FMDatabaseQueue *dataBaseQueue;
@end;
@implementation DataBaseManager
+ (instancetype)sharedManager {
static DataBaseManager *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[DataBaseManager alloc] init];
});
return manager;
}
- (instancetype)init
{
self = [super init];
if (self) {
//初始化数据库
[self initDataBase];
}
return self;
}
- (void)initDataBase {
//获取Documents目录路径
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//文件路径
NSString *filePath = [documentPath stringByAppendingPathComponent:@"contact.db"];
//实例化FMDB
_dataBaseQueue = [FMDatabaseQueue databaseQueueWithPath:filePath];
//创建项目需要的数据库表
[self initContactTable];
}
- (void)initContactTable
{
[_dataBaseQueue inDatabase:^(FMDatabase *db) {
//创建用户信息表
BOOL result2 = [db executeUpdate:@"create table if not exists contact_userdetail(id integer Primary Key Autoincrement, userid text, object blob);"];
if (result2) {
NSLog(@"contact_user 表创建成功");
}
}];
}
#pragma mark - UserDetailOperate Methods
- (BOOL)updateUserDetail:(UserDetailModel *)userDetail {
//查询该数据是否存在
__block BOOL result = NO;
[_dataBaseQueue inDatabase:^(FMDatabase *db) {
FMResultSet *resultSet = [db executeQuery:@"select object from contact_userdetail where userid = ?;", userDetail.userid];
if (resultSet.next) {
NSData *data = [resultSet dataForColumn:@"object"];
//数据存在
if (data) {
//取出数据,打印一下userid
UserDetailModel *model = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"userid : %@", model.userid);
}
//数据存在,更新数据
NSData *userDetailData = [NSKeyedArchiver archivedDataWithRootObject:userDetail];
result = [db executeUpdate:@"update contact_userdetail set object = ? where userid = ?", userDetailData, userDetail.userid];
if (result) {
NSLog(@"数据更新成功");
} else {
NSLog(@"数据更新失败");
}
} else {
//数据不存在,插入一条数据
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:userDetail];
result = [db executeUpdate:@"insert into contact_userdetail (userid, object) values (?, ?);", userDetail.userid, data];
if (result) {
NSLog(@"数据插入成功");
} else {
NSLog(@"数据插入失败");
}
}
[resultSet close];
}];
return result;
}
- (BOOL)deleteUserDetail:(UserDetailModel *)userDetail {
__block BOOL result = NO;
[_dataBaseQueue inDatabase:^(FMDatabase *db) {
result = [db executeUpdate:@"delete from contact_userdetail where userid = ?", userDetail.userid];
}];
return result;
}
- (UserDetailModel *)getUserDetailByUserId:(NSString *)userid {
__block UserDetailModel *model = nil;
[_dataBaseQueue inDatabase:^(FMDatabase *db) {
FMResultSet *set = [db executeQuery:@"select * from contact_userdetail where userid = ?", userid];
if (set.next) {
NSData *data = [set dataForColumn:@"object"];
model = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
[set close];
}];
return model;
}
- (NSArray<UserDetailModel *> *)getAllUsersDetail {
__block NSMutableArray *array = [NSMutableArray array];
[_dataBaseQueue inDatabase:^(FMDatabase *db) {
FMResultSet *set = [db executeQuery:@"select * from contact_userdetail"];
while (set.next) {
NSData *data = [set dataForColumn:@"object"];
UserDetailModel *model = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[array addObject:model];
}
[set close];
}];
return [NSArray arrayWithArray:array];
}
至此,关于UserDetailModel增删改查数据库操作就基本完成了。