简介
简单整理一些FMDB
的一些常用操作.
需要了解的概念包括但不限于外连接,表别名,唯一键,升序,游标,like,between and,not null,unique,default,check,primary key, foreing key,union等等,更多查看sqlite关键字
CRUD,连表查询,索引,事务,回滚
CRUD
创建数据库文件,一般有两种方法,一是新建一个文件,然后后缀名修改为自定义后缀,然后直接拖到项目的main bundle,还有一种是获取当前app的沙盒路径,然后在目录下面新建一个文件作为数据库文件.123456789101112// create// 第二种方法示例:// 全局db路径_dbPath = [path stringByAppendingPathComponent:kDBFileName];NSError *error = nil;// path 为初始化传入的路径,判断路径下面是否存在数据库文件if (![[NSFileManager defaultManager] createDirectoryAtPath:pathwithIntermediateDirectories:YESattributes:nilerror:&error]) {NSLog(@"init error:%@", error);}建表
1234567create table if not exists t_Stuent (sid text,name text,insert_time integer,extended_data blob,primary key(sid));插入
1234567// 普通插入NSString *sql = @"INSERT INTO aTable(itemInfoId,userName,userId,cacheTime) VALUES (?1,?2,?3,?4)";// 插入或替换NSString *sql = @"INSERT OR REPLACE INTO aTable(itemInfoId,userName,userId,cacheTime) VALUES (?1,?2,?3,?4)";// 插入或忽略NSString *sql = @"INSERT OR IGNORE INTO aTable(itemInfoId,userName,userId,cacheTime) VALUES (?1,?2,?3,?4)";[db executeUpdate:sql, item.itemInfoId,item.userName, item.userId, [NSDate new]]查询
1NSString *sql = @"SELECT * FROM aTable WHERE cacheTime < ? and itemInfoId = ? and workspaceItemInfoId is not null ORDER BY cacheTime DESC LIMIT 0,20;";更新
1NSString *sql = @"UPDATE aTable SET cacheTime = ? WHERE itemInfoId = ?;"删除
123[db executeUpdate:@"DELETE FROM aTable WHERE itemInfoId = ?;", item.itemInfoId];// 删除表@"DROP TABLE aTable";连表查询
1234567// 一般查询select * from aTable,bTable where aTable.id=aTable.id;// 内连接select a.name, b.name from aTable as a inner join bTable as b on a.id = b.id// 左连接select * from aTable left outer join bTable on aTable.id=bTable.id// 不支持右连接和全连接-
12// 索引可以提高查询效率,但是生成索引需要更大的存储空间create index if not exists idxName on t_Stuent(name);
事务
1234567FMDatabase *db;// 开始事务,内部执行sql语句 begin exclusive transaction[db beginTransaction];// 开始事务,内部执行sql语句 begin deferred transaction[db beginDeferredTransaction]// 提交,内部执行sql语句 commit transaction[db1 commit];两种开启事务的区别SQLite语法 BEGIN TRANSACTION
回滚
1234567[[FMDatabaseQueue sharedInstance] inDeferredTransaction:^(FMDatabase *db, BOOL *rollback) {// 出错, 执行回滚操作// 内部执行 [self executeUpdate:@"rollback transaction"]if (error) {*rollback = YES;}}];数据库语句缓存
12// 提高查询效率,实际使用字典进行缓存FMStatement[db setShouldCacheStatements:YES];
增加表字段,修改表名,修改数据库名称
增加表字段ALTER TABLE aTable ADD COLUMN name TEXT
更改表名称ALTER TABLE "aTable" RENAME TO "aTable_old_20170831";
表迁移数据
因为sqlite不支持直接修改某一列数据,可以将表A重命名为临时表B,然后,新建一个A表,将B表数据拷贝到A表中,然后删除临时表B即可
pragma扩展语句
PRAGMA语句是SQLITE数据的SQL扩展,是它独有的特性,主要用于修改SQLITE库或者内数据查询的操作。
SQLite中的PRAGMA语句攻略pragma journal_mode = wal;
默认delete
,开启wal
模式之后,一般情况下写入性能更好.会生成两个文件:.shm和.walpragma synchronous = normal;
在sqlite3.0中默认为full
,防止设备故障导致数据库损坏,但是读取性能差,off
性能更好,但是对数据库保护不够,一般使用normal
模式
加密
加密你的SQLite
我选择的是sqlcipher,FMDB也有加密的分支,可以通过CocoaPods安装
初始化的时候调用db的setKey:
就可以了
新的数据库方案
微信团队开源了一个数据库解决方案,叫做[WCDB](https://github.com/Tencent/wcdb)
,性能和安全性都通过博客看,非常不错,可以阅读他们的以下文章,进行了解学习
微信iOS SQLite源码优化实践
微信 SQLite 数据库修复实践
微信WCDB进化之路 - 开源与开始
微信移动端数据库组件WCDB系列(一)-iOS基础篇
微信移动端数据库组件WCDB系列(二) — 数据库修复三板斧
微信移动端数据库组件WCDB系列(三) — WINQ原理篇
微信移动数据库组件WCDB(四) — Android 特性篇
为什么要从FMDB迁移到WCDB?