IOS数据四种存储方法:
- 通过基本数据类型(如NSString存储在内存内),无法持久化存储;
- 通过NSDefualt存储,可持久化存储。但这种存储方式是key-value方式,不能存储大量数据;
- 通过SQLit存储,存入数据库,可持久化存储。但SQLit用C编写代码,代码任务繁重;
- 通过苹果自带的coredata存储,存入数据库,可持久化存储,但操作依然繁琐;
- 通过第三方库存储(如FMDB、MagicalRecord),可持久化存储,并且简单易操作。
最近有项目用到数据库存储,存储方式是用第三方库FMDB,特在此mark一下。
FMDB特点:
- 不用编写冗长的C代码;
- 比coredata更轻量级,更灵活;
- 提供多线程安全,防止数据库混乱。
FDMB库文件:
- FMDatabase:提供SQLit数据库,执行SQL语句;
- FMResultSet:执行查询结果;
- FMDatabaseQueue:提供多线程下的数据库操作。
FDMB第三方库导入:
使用CocoaPods导入第三方库,在后端进入工程文件,用vim命令创建podfile文件,并填入内容:
platform :ios, '8.0'
target 'FMDBDemo' do
pod 'FMDB', '~> 2.6'
end
之后保存并退出,再用pod install命令导入FMDB。
FMDB增查改删方法总结
1 将数据存入数据库,以Person为例,假设Person有三个属性,定义八个数据库操作方法:
@interface Person : NSObject
@property(nonatomic, strong) NSString *name;
@property(nonatomic, strong) NSString *idNumber;
@property(nonatomic, strong) NSString *country;
+ (BOOL)save:(Person *)person;
+ (BOOL)update:(Person *)person;
+ (NSMutableArray *)fetchAll;
+ (NSMutableArray *)fetchByName:(NSString *)name;
+ (BOOL)deleteAll;
+ (BOOL)deleteByIdNumber:(NSString *)idNumber;
+ (BOOL)deleteMultipleItems;
+ (NSInteger)dbCount;
@end
并定义两个宏:
#define DATABASE_PATH NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]//生成数据库存储地址
#define FMDBQuickCheck(SomeBool) { if (!(SomeBool)) { NSLog(@"Failure on line %d", __LINE__); abort(); } }//检测数据库操作方法是否成功
在保存数据时,要先确定数据表是否存在,若不存在则需要建立数据表,之后将数据存入数据库。注意,对于返回类型为BOOL类型的数据库操作,一般使用executeUpdate方法;返回类型为非BOOL类型(即从数据库中取得数据时)一般使用executeQuery方法。保存数据代码如下:
+ (BOOL)save:(Person *)person {
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return NO;
}
NSString *createStr = @"create TABLE if not exists 'PERSON'('name' varchar not null, 'idNumber' varchar primary key unique not null, 'country' varchar not null)";
BOOL worked = [db executeUpdate:createStr];
FMDBQuickCheck(worked);
NSString *insertStr = @"replace into 'PERSON'('name', 'idNumber', 'country')values(?,?,?)";
worked = [db executeUpdate:insertStr, person.name, person.idNumber, person.country];
FMDBQuickCheck(worked);
[db close];
return worked;
}
2 更新数据库数据:
+ (BOOL)update:(Person *)person {
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return NO;
}
NSString *updateStr = @"update Person set name = ? where idNumber = ?";
BOOL woked = [db executeUpdate:updateStr, person.idNumber];
FMDBQuickCheck(woked);
[db close];
return woked;
}
3 查询所有数据:
+ (NSMutableArray *)fetchAll {
NSMutableArray *all = [[NSMutableArray alloc] init];
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return all;
}
NSString *fetchStr = @"select * from PERSON";
FMResultSet *rs = [db executeQuery:fetchStr];
while ([rs next]) {
Person *person = [[Person alloc] init];
[person setName:[rs stringForColumn:@"name"]];
[person setIdNumber:[rs stringForColumn:@"idNumber"]];
[person setCountry:[rs stringForColumn:@"country"]];
[all addObject:person];
}
[db close];
return all;
}
4 按条件查询数据:
+ (NSMutableArray *)fetchByName:(NSString *)name {
NSMutableArray *all = [[NSMutableArray alloc] init];
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return all;
}
NSString *fetchStr = @"select * from PERSON where name = ?";
FMResultSet *rs = [db executeQuery:fetchStr, name];
while ([rs next]) {
Person *person = [[Person alloc] init];
[person setName:[rs stringForColumn:@"name"]];
[person setIdNumber:[rs stringForColumn:@"idNumber"]];
[person setCountry:[rs stringForColumn:@"country"]];
[all addObject:person];
}
[db close];
return all;
}
5 删除所有数据
+ (BOOL)deleteAll {
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return NO;
}
NSString *deleteStr = @"delete from PERSON";
BOOL worked = [db executeUpdate:deleteStr];
FMDBQuickCheck(worked);
[db close];
return worked;
}
6 按条件删除数据:
+ (BOOL)deleteByIdNumber:(NSString *)idNumber {
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"数据库打开失败");
return NO;
}
NSString *deleteStr = @"delete from PERSON where idNumber = ?";
BOOL worked = [db executeUpdate:deleteStr, idNumber];
FMDBQuickCheck(worked);
[db close];
return worked;
}
7 删除一部分数据,如删除前10000条数据
+ (BOOL)deleteMultipleItems {
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"打开数据库失败");
return NO;
}
BOOL worked = [db executeUpdate:@"delete from PERSON where (select count(*) from PERSON)> 10000 and idNumber in (select * from PERSON order by idNumber ASC limit 10000)"];//删除前10000条数据
FMDBQuickCheck(worked);
[db close];
return worked;
}
8 获取数据库大小:
+ (NSInteger)dbCount {
NSInteger dbCounts = -1;
FMDatabase *db = [[FMDatabase alloc] initWithPath:[DATABASE_PATH stringByAppendingString:@"/PERSON.db"]];
if (![db open]) {
NSLog(@"打开数据库失败");
return dbCounts;
}
NSString *countStr = @"select count(*) from PERSON";
FMResultSet *rs = [db executeQuery:countStr];
if ([rs next]) {
dbCounts = [rs intForColumnIndex:0];
}
return dbCounts;
}
多线程下的操作还未涉及,目前还在学习中,之后更新。