在一些APP中,开发者需要对一些数据保存到本地进行维护,如QQ的好友列表,消息列表等都是通过在本地数据库进行管理的。
在我的工程我也使用了数据库来对数据进行一些本地的维护操作,如对联系人列表、联系人信息,登陆后的个人信息等。
本文主要介绍利用FMDB对数据库进行简单的增删改查操作。考虑到代码可读性、后期可维护性以及程序运行中的线程安全问题,数据库的所有操作都放在DBHelp单例类中完成。
1、导入
我们可以通过Pod倒入或者直接拖到工程目录下,如果没有安装Pod需要先安装Pod,
我使用的是Pod来管理第三方库,在Podfile文件中输入:
pod 'FMDB'
如果不用Pod,可到Github下载改框架,然后直接拖到工程中即可。
FMDB结构如上图所示,fmdb的主要类结构为3个,FMDatabase,FMdatabaseQueue,FMResultSet;
(1)、FMDatabase类主要用来执行增删改查等相关操作的SQL语句;
(2)、FMdatabaseQueue类主要是在多线程中的操作,保证线程安全;
(3)、FMResultSet类主要用于执行查询后返回的数据;
2、FMDB关键字
create、drop、insert、update、delete、select、where等等、、
更多SQL请参考:SQL 语法。
其他:SQL语法对大小写不敏感,也就是说,下面这两种SQL语法执行后的结果是相同的,都是查询一张表中的所有数据;
SELECT * FROM tableName
select *from tableName
FMDB的相关操作也很简单,下面请看利用FMDB对本地的数据进行管理;
3、新建数据库:
-(void)CreateMyServer{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *dbPath = [documentDirectory stringByAppendingPathComponent:@"myserver.db"]; NSString*documentDirectory = [pathsobjectAtIndex:0]; self.dataBase = [FMDatabase databaseWithPath:dbPath]; }
考虑到数据安全问题,防止APP在被反编译后用户数据泄漏,需要对数据库进行加密操作:
#import <sqlite3.h>
#import "FMDB.h"
#import <CommonCrypto/CommonDigest.h>
#import <UIKit/UIDevice.h>
///默认起始索引
static NSString *constindexID = @"1000";
///数据库名
static NSString *constServerName = @"DBServer";
/////
static NSString *constDBName = @"fmdb_demo.db";
@property (nonatomic, strong) FMDatabase *dataBase;
/** * 新建一个数据库, * ServerName 数据库名称 * DBName */ -(BOOL)CreateMyServer :(NSString*)ServerName mydbName:(NSString*)mydbName { if(ServerName.length == 0) { return NO; } NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); //username md5 constchar*cStr = [ServerName UTF8String]; unsigned char result[16]; CC_MD5(cStr, (CC_LONG)strlen(cStr), result); NSString* MD5 = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],result[8], result[9], result[10], result[11],result[12], result[13], result[14], result[15]]; NSString * documentsDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:MD5]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir = FALSE; BOOL isDirExist = [fileManager fileExistsAtPath:documentsDirectory isDirectory:&isDir]; if(!(isDirExist && isDir)) { BOOL bCreateDir = [fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:nil]; if(!bCreateDir) { NSLog(@"Create Database Directory Failed."); return NO; }else { return YES; } } NSString*dbPath = [documentsDirectorystringByAppendingPathComponent:mydbName]; self.dataBase = [FMDatabase databaseWithPath:dbPath]; }
4、打开数据库
-(void)OpneServerData{ NSString*dbPath = [documentsDirectory stringByAppendingPathComponent:mydbName]; //判断数据库是否已存在 if(self.dataBase) { [self.dataBase close]; self.dataBase=nil; } self.dataBase = [FMDatabase databaseWithPath:dbPath]; [self.dataBase open]; if(!self.dataBase) { printf("\n\n========打开数据库失败"); }else { printf("\n\n========打开数据库成功"); } }
5、新建表
SQL语法: [self createTable:@"tableName" sql:@"CREATE table userInfo (id TEXT NOT NULL PRIMARY KEY UNIQUE ON CONFLICT REPLACE, userId TEXT, nickName TEXT, sex INTEGER)"];
- (BOOL) createTable:(NSString*)tableName sql:(NSString*)createSql {
BOOL isExist = [self.dataBase tableExists:tableName];
if(!isExist) {
[self.dataBase executeUpdate:createSql];
printf("\n\n\ncreate the table success");
returnYES;
}else {
printf("\n\n\ncreate the table Failed.");
returnNO;
}
}
6、删除指定表
DELETE FROM tableName
- (BOOL)runSql:(NSString*)sql { return [self.dataBase executeUpdate:sql]; } - (BOOL)deleteWithTable:(NSString*)tableName { return [self runSql:[NSString stringWithFormat:@"DELETE FROM %@",tableName]]; }
7、插入数据
INSERT INTO tableName (id,key1,key2,key3) values(?,?,?,?)",constindexID,参数1,参数2,参数3
- (BOOL)inserttableName:(NSString*)tableName nickName:(NSString*)nickName infoID:(NSString*)infoID userID:(NSString*)userId sex:(NSString*)sex
{
BOOL insert = [self.dataBase executeUpdate:@"INSERT INTO tableName (id,userid,nickName,sex) values(?,?,?,?)",infoID,userId,nickName,sex];
if(insert) {
printf("\ninsert the data success");
retrun YES;
}else {
printf("\ninsert the data Failed.");
retrun NO;
}
}
8、更新数据
(1)、通过索引修改某一条数据;
如:把表中索引为1000的数据性别修改为男;
UPDATE tableName SET sex = '男' WHERE id = '1000'
NSString*sql = @"UPDATE tableName SET sex = '男' WHERE id = '1000'";
[self.dataBase executeUpdate:sql];
9、查询
查询分很多种情况:查询一张表的所有数据,按照索引(或者id)查询某张表的所有数据,多张表的联合查询等;
(1)、查询一张表的所有数据
SQL语法:SELECT * FROM tableName
//查询表里面的所有数据
FMResultSet *s = [dbexecuteQuery:@"SELECT * FROM tableName"];
while([snext])
{
//循环所有的查询的所有值
}
(2)、通过索引查询某一行的数据
SQL语法:SELECT 1000 FROM tableName
NSString *sql = @"SELECT 1000 FROM tableName";
FMResultSet *rs = [self.dataBase executeQuery:sql];
if([rsnext])
{
}else{
}
(3)、通过索引查询某一条数据
如:我要查询表中索引为1000的这条数据的人员的性别:
NSString *sql = @" SELECT sex FROM tableName WHERE id = '1000'";
FMResultSet *rs = [self.dataBase executeQuery:sql];
if([rsnext])
{
}else{
}
网友评论