FMDB/SQLCipher数据库管理
FMDB/SQLCipher数据库管理
我爱觉觉 发表于3年前
FMDB/SQLCipher数据库管理
  • 发表于 3年前
  • 阅读 71
  • 收藏 1
  • 点赞 0
  • 评论 0

移动开发云端新模式探索实践 >>>   

摘要: 数据库加密一般有两种方式1、对所有数据进行加密2、对数据库文件加密。这里主要说的是对数据库文件的加密。
  1. 安装cocopods。http://my.oschina.net/u/2418942/blog/508913。

  2. 安装  pod "FMDB/SQLCipher"。如果安装有问题,可以先对cocopods进行update一下。

  3. 修改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

   如果没有加密建立的数据库,想再加密,那么必须把原有数据库删除,不然会报错。

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 2
博文 49
码字总数 10640
×
我爱觉觉
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: