安装cocopods。http://my.oschina.net/u/2418942/blog/508913。
安装 pod "FMDB/SQLCipher"。如果安装有问题,可以先对cocopods进行update一下。
修改FMDatabase文件。添加一个宏定义,修改2个方法。添加的代码用_标出。把带_的代码删除,即可恢复。
#define DB_SECRETKEY @"HPSQLDatabase"
- (BOOL)open {
if (_db) {
return YES;
}
int err = sqlite3_open([self sqlitePath], &_db );
if(err != SQLITE_OK) {
NSLog(@"error opening!: %d", err);
return NO;
}else if (err == SQLITE_OK)
{
[self setKey:DB_SECRETKEY];
}
if (_maxBusyRetryTimeInterval > 0.0) {
// set the handler
[self setMaxBusyRetryTimeInterval:_maxBusyRetryTimeInterval];
}
return YES;
}
- (BOOL)openWithFlags:(int)flags {
if (_db) {
return YES;
}
int err = sqlite3_open_v2([self sqlitePath], &_db, flags, NULL /* Name of VFS module to use */);
if(err != SQLITE_OK) {
NSLog(@"error opening!: %d", err);
return NO;
} else if (err == SQLITE_OK) {
[self setKey:DB_SECRETKEY];
}
if (_maxBusyRetryTimeInterval > 0.0) {
// set the handler
[self setMaxBusyRetryTimeInterval:_maxBusyRetryTimeInterval];
}
return YES;
}
4. 建立sql语句文件。databasefile.sql
CREATE TABLE IF NOT EXISTS "databaseName" (
"did" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"createTime" TEXT
)
5. 建立SQLManager文件。SQLiteManager.h和SQLiteManager.m文件
+ (instancetype)sharedSQLiteManager {
static SQLiteManager* manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[SQLiteManager alloc] init];
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:@"databaseName.db"];
NSLog(@"SQLitePath ---- %@",path);
manager.queue = [[FMDatabaseQueue alloc] initWithPath:path];
[manager creatTable];
});
return manager;
}
- (void)creatTable {
NSString* path = [[NSBundle mainBundle] pathForResource:@"databasefile.sql" ofType:nil];
NSError* error;
NSString* statement = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
LogE(@"创表字符串错误 ----- %@",error);
}
[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
if ([db executeUpdate:statement]) {
NSLog(@"%@创表成功",sqlStr);
}else{
LogE(@"%@创表失败",sqlStr);
return;
}
}];
}
}
- (void)openDateBase {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:@"databaseName.db"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
LogE(@"数据库打开失败!");
}
}
- (void)closeDateBase {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:@"databaseName.db"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db close]) {
LogE(@"数据库关闭失败!");
}
}
// 获取所有信息
- (NSMutableArray *)loadAll {
[self openDateBase];
NSString* loadStatement = @"SELECT * FROM databaseName ORDER BY did ASC;";
NSMutableArray* tempArray = [NSMutableArray array];
[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
FMResultSet* result = [db executeQuery:loadStatement];
while ([result next]) {
Detail* detail = [[Detail alloc] init];
detail.dId = [NSNumber numberWithInt:[result intForColumn:@"did"]];
detail.name = [result stringForColumn:@"name"];
detail.createTime = [result stringForColumn:@"createTime"];
[tempArray detail];
}
}];
[self closeDateBase];
return tempArray;
}
// 插入数据
- (void)insertData:(Detail*)detail{
[self openDateBase];
NSString* insertStatement = @"INSERT INTO databaseName (name,createTime) VALUES (?,?);";
[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
if ([db executeUpdate:insertStatement withArgumentsInArray:@[detail.name,getail.createTime]]) {
NSLog(@"添加成功");
}else{
LogE(@"添加失败");
}
}];
[self closeDateBase];
}
// 更新信息
- (void)updatedata:(Detail*)detail{
NSString* updateStatement = @"UPDATE databaseName SET name = ? WHERE did = ?;";
[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:updateStatement withArgumentsInArray:@[detail.name,detail.dId]];
}];
}
// 删除
- (void)deleteGroup:(Detail*)detail{
NSString* deleteStatement = [NSString stringWithFormat:@"DELETE FROM databaseName WHERE did = ?;"];
[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
if ([db executeUpdate:deleteStatement withArgumentsInArray:@[detail.dId]]) {
NSLog(@"删除成功");
}else {
NSLog(@"删除失败");
}
}];
}
6. 在viewController调用
#import "SQLiteManager.h"
@property (strong, nonatomic) SQLiteManager *manager;
- (void)viewDidLoad {
[super viewDidLoad];
SQLiteManager *manager = [SQLiteManager sharedSQLiteManager];
self.manager = manager;
}
然后就可以调用方法了。
7. 在本地文件夹中找到数据库,用Navicat Premium 工具打开,会提示“file is encrypted or is not a database”。这表示你的数据库已经加密了。(如果不做加密的那步骤,在这里是可以用工具打开数据库的)。
8. 提示: 数据库字段名字不能用group
如果没有加密建立的数据库,想再加密,那么必须把原有数据库删除,不然会报错。