SQLite:
SQLite是一款轻量级型的数据库,资源占用少、性能良好和零管理成本,具有零配置(无需安装和管理配置)、独立(没有额外依赖)、储存在单一磁盘文件中的一个完整的数据库、源码完全的开源、比一些流行的数据库在大部分普通数据库操作要快……功能特性;在大型系统和处理大批量数据时不适用
SQLite引擎不是程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分,所以主要的通信协议是在编程语言内的直接API调用;在APP开发中将SQLite集成到应用的沙盒目录下(SQLite是以文件形式存在),用于缓存数据到本地,通过Objective-C可以直接调用SQLite的API来访问本地数据
SQLite在iOS开发通常不直接使用,API代码调用很繁琐,因此一般使用第三方框架FMDB或iOS封装的原生的CoreData;使用SQLite需要导入最新SQLite 3.0/SQLite 3框架,而且可以通过代码直接创建SQLite文件和表,需要注意的是数据库每次操作前都需要开库,在每次操作完毕后都需要关闭数据库;如果直接使用SQLite还需要通过FireFox的SQLite Manager创建SQLite文件和表
FMDB:
FMDB是对操作SQLite的封装,框架实现了通过代码直接创建表的功能,建表前判断表是否存在,不存在才创建,因此开库操作就是调用建表方法;FMDB将对数据库的操作分为两类:修改(update)和查询(query)
FMDB只是封装了对SQLite的操作,因此在使用时还需要创建数据库管理类:DBManager,其对建表(开库)、操作类型(每次操作完后关库)进行封装;当数据库和模型绑定时,需要在数据库的操作类型中进行数据的模型化操作,操作模型即能实现和数据库的关联,而且每一种操作类型都能被够复用
1. FMDB的下载地址 https://github.com/ccgus/fmdb
2. 在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包
3. FMDB常用类
FMDatabase : 一个单一的SQLite数据库,用于执行SQL语句。
FMResultSet :执行查询一个FMDatabase结果集。
FMDatabaseQueue :在多个线程来执行查询和更新时会使用这个类
对FMDB操作类型的封装,DMManager类封装的对数据的增删改查、指定查询、建表(开库)、模型转换操作
#import "DBMamager.h" #import "FMDB.h" // 宏定义表的关键字 #define TABNAME @"MEMBER" #define ID @"MEMID" #define NAME @"MEMNAME" #define SEX @"MEMSEX" #define TEL @"MEMTEL" #define QQ @"MEMQQ" #define DB @"member.sqlite" @interface DBMamager () @property (nonatomic, strong)FMDatabase *db; @property (nonatomic, strong)NSString *pathDB; @end @implementation DBMamager // 建表 - (void)createDB { _pathDB = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:DB]; _db = [FMDatabase databaseWithPath:_pathDB]; if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"create table if not exists '%@' ('%@' integer primary key autoincrement, '%@' varchar(20), '%@' varchar(10),'%@' varchar(20),'%@' varchar(20))", TABNAME, ID, NAME, SEX, QQ, TEL]; [_db executeUpdate:sql]; } [_db close]; } // 查询所有 - (NSMutableArray *)getallMember { NSMutableArray *stus = [NSMutableArray array]; if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"select * from %@", TABNAME]; FMResultSet *resultSet = [_db executeQuery:sql]; while (resultSet.next) { Member *mem = [[Member alloc] initWithDic: @{@"memid":@([resultSet intForColumn:ID]), @"name":[resultSet stringForColumn:NAME], @"sex":[resultSet stringForColumn:SEX], @"qq":[resultSet stringForColumn:QQ], @"tel":[resultSet stringForColumn:TEL] }]; [stus addObject:mem]; } } [_db close]; return stus; } // 增加 - (BOOL)insertMember:(Member *)mem { if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"insert into %@(%@, %@, %@, %@) values('%@', '%@', '%@', '%@')", TABNAME, NAME, SEX, QQ, TEL, mem.name, mem.sex, mem.qq, mem.tel]; return [_db executeUpdate:sql]; } [_db close]; return NO; } // 删除 - (BOOL)deleteMember:(NSInteger)memid { if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"delete from %@ where %@ = %lu", TABNAME, ID, memid]; return [_db executeUpdate:sql]; } [_db close]; return NO; } // 修改 - (BOOL)updateMember:(Member *)mem { if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"update %@ set %@ = '%@', %@ = '%@', %@ = '%@', %@ = '%@' where %@ = %lu", TABNAME, NAME, mem.name, SEX, mem.sex, QQ, mem.qq, TEL, mem.tel, ID, mem.memid]; return [_db executeUpdate:sql]; } [_db close]; return NO; } // 指定memid查询 - (Member *)selectMember:(NSInteger)memid { if ([_db open]) { NSString *sql = [NSString stringWithFormat:@"select * from %@ where %@ = %lu", TABNAME, ID, memid]; FMResultSet *resultSet = [_db executeQuery:sql]; while (resultSet.next) { Member *mem = [[Member alloc] initWithDic: @{@"memid":@([resultSet intForColumn:ID]), @"name":[resultSet stringForColumn:NAME], @"sex":[resultSet stringForColumn:SEX], @"qq":[resultSet stringForColumn:QQ], @"tel":[resultSet stringForColumn:TEL] }]; return mem; } } return nil; } @end
4. 如果应用中使用了多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 应用中不可在多个线程中共同使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱。 为了多线程操作数据库安全,FMDB使用了FMDatabaseQueue,使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使 化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理
//2多线程操作
NSString *path=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
path=[path stringByAppendingPathComponent:@"test.sqlite"];
FMDatabaseQueue * queue=[FMDatabaseQueue databaseQueueWithPath:path];
[queue inDatabase:^(FMDatabase *db) {
NSString * create=@"create table if not exists t_book(id integer,name varchar)";
BOOL c1= [db executeUpdate:create];
if(c1){
NSLog(@"成功");
}
}];
[queue inDatabase:^(FMDatabase *db) {
NSString * insertSql=@"insert into t_book(id,name) values(?,?)";
//插入语句1
bool inflag=[db executeUpdate:insertSql,@(2),@"admin"];
if(inflag){
NSLog(@"插入成功");
}
}];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet * data=[db executeQuery:@" select * from t_book "];
while (data.next) {
int ids=[data intForColumn:@"id"];
NSString *name=[data stringForColumn:@"name"];
NSLog(@"%@",name);
NSLog(@"%i",ids);
}
}];
FMDB是对操作SQLite的封装,框架实现了通过代码直接创建表的功能,建表前判断表是否存在,不存在才创建,因此开库操作就是调用建表方法;FMDB将对数据库的操作分为两类:修改(update)和查询(query)
FMDB只是封装了对SQLite的操作,因此在使用时还需要创建数据库管理类:DBManager,其对建表(开库)、操作类型(每次操作完后关库)进行封装;当数据库和模型绑定时,需要在数据库的操作类型中进行数据的模型化操作,操作模型即能实现和数据库的关联,而且每一种操作类型都能被够复用