一、Sqlite(FMDB)
以前火狐有插件支持在线编辑sqlite文件,新版火狐不好用了,在前几篇文章中提到的有sqlte工具
下面是详细实现过程及代码,有需要的可以去下载整理好的文件该文件未引入FMDB包所以不能直接运行,复制代码至你的项目中使用,集成FMDB 1.手动下载FMDB包导入依赖库;2.使用pod管理第三方库,使用方法下述链接有详细说明
pod集成链接:
下载地址:
1.初始化
通过上述工具生成db文件,可以通过工具可视化界面创建表、添加初始字段,拖至项目中使用时通过单例copy至项目沙盒路径下(省去代码创建表、字段操作),不理解可以直接复制代码查看
2.copy初始db文件至沙盒中,并获取表的所有字段,为后续操作提供数据
+(void)initialize{
//1.将数据库copy到document下(一些已有的数据 表等可以直接用)
[DataBaseEnginer copyDBToDocument];
//2.获取数据库中某个表的所有列名
//这里是项目中三个表,分别获取每个表的所有字段,(KTableCarName--对应创建的表名)
tableCloumn = [DataBaseEnginer getColumnNameForTable:KTableCarName];
huowuTableCloumn = [DataBaseEnginer getColumnNameForTable:KTableHuowuName];
moneyCountTableCloumn = [DataBaseEnginer getColumnNameForTable:KTablemoneyCountName];
}
//复制db文件至沙盒
+(void)copyDBToDocument{
//1.获取app中的数据库路径
NSString *DBpath = [[NSBundle mainBundle] pathForResource:KDBName ofType:nil];
//2.获取document的路径
NSString *toPath = [FileOpretions filePath:KDBName];
NSLog(toPath);
//3.copy DB到document下面
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:toPath]) {
[manager copyItemAtPath:DBpath toPath:toPath error:nil];
}
}
//获取所有列表,某个表
+(NSArray *)getColumnNameForTable:(NSString *)tableName{
//1.创建db 打开
FMDatabase *db = [FMDatabase databaseWithPath:[FileOpretions filePath:KDBName]];
[db open];
//2.执行操作 查询出所有的字段名
//这是获取表中所有的列 以及这一列的描述
FMResultSet *reslutSet = [db getTableSchema:tableName];
NSMutableArray *resultArray = [NSMutableArray array];
while ([reslutSet next]) {
NSString *cloumn = [reslutSet objectForColumnName:@"name"];
[resultArray addObject:cloumn];
}
[db close];
return resultArray;
}
3.增删改查
1.提供一个批量插入的,单个插入自行解决也可以调用批量插入,这里传的是数组--里面是字典通过对比key跟数据库字段名字来对比
//插入数据
//[FileOpretions filePath:KDBName] --- 为获取沙盒中db数据库的方法,我是抽出个类,下面提供方法
//由于OC限制 出基础类数据,对象不能直接插入到数据库,这里需要序列化处理,获取的时候要解析
+(BOOL)saveStatusToDB:(NSArray *)statusInfo{
//一次操作太多数据 用队列更好 不在主线程操作
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[FileOpretions filePath:KDBName]];
[queue inDatabase:^(FMDatabase *db) {
//队里不需要管理 数据库的开启关闭
for (NSDictionary *dic in statusInfo) {
//1.数据库的字段是所有数据的 可能这一次返回的数据中没有这个字段的数据
// 这里先筛选出跟数据库都有的字段 在执行插入操作
NSArray *resultKeys = [DataBaseEnginer contentValuesWith:dic.allKeys DBCloumn:tableCloumn];
//有些返回的数据是一个字典 或者数组 在这转换成data 在存入到数据库中
NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary];
[resultKeys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//通过键 获取值 判断是什么类型的 数字 字典不能直接存
id value = dic[obj];
if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
//归档就是转换成 二进制数据的
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
[mutableDic setObject:data forKey:obj];
}else{
[mutableDic setObject:value forKey:obj];
}
}];
//构造sql语句
NSString *sql = [DataBaseEnginer getSqlWith:resultKeys];
//执行SQL语句
[db executeUpdate:sql withParameterDictionary:mutableDic];
}
}];
return YES;
}
+(NSArray *)contentValuesWith:(NSArray *)statusCloumn DBCloumn:(NSArray *)DBCloumn{
NSMutableArray *arr = [NSMutableArray array];
//遍历数据库的所有字段 跟返回的数据字段对比 有的就存入数组中 没有就不考虑
[statusCloumn enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([DBCloumn containsObject:obj]) {
[arr addObject:obj];
}
}];
return [arr copy];
}
+(NSString *)getSqlWith:(NSArray *)allKeys{
NSString *cloumnString = [allKeys componentsJoinedByString:@", "];
NSString *values = [allKeys componentsJoinedByString:@",:" ];
values = [@":" stringByAppendingString:values];
NSString *sql = [NSString stringWithFormat:@"insert into %@(%@) values(%@)",KTableCarName,cloumnString,values];
return sql;
}
+(NSString *)filePath:(NSString *)fileName{
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [path stringByAppendingPathComponent:fileName];
return filePath;
}
2.修改
修改分为两种,1.直接写sql 字符串来处理修改---适用于更改字段较少,基本数据类型
2.通过字典键值对拼接----适用于更该字段较多,有对象类型
//更新本地存放数据状态 --常规未提交 本地修改更改 依据车牌、创建时间修改
+(BOOL)updateStatebyInfo:(NSDictionary *)info carName:(NSString *)carName andTime:(NSString *)time{
if (carName.length>0 && time.length>0) {
FMDatabase *db = [FMDatabase databaseWithPath:[FileOpretions filePath:KDBName]];
[db open];
NSArray *resultKeys = [DataBaseEnginer contentValuesWith:info.allKeys DBCloumn:tableCloumn];
NSMutableString *sql = [NSMutableString stringWithFormat:@"update %@ set ",KTableCarName];
NSMutableArray *dataArray = [NSMutableArray array];
[resultKeys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//通过键 获取值 判断是什么类型的 数字 字典不能直接存
[sql appendFormat:@"%@=?,",obj];
id value = info[obj];
if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
//归档就是转换成 二进制数据的
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
[dataArray addObject:data];
}else{
[dataArray addObject:value];
}
}];
NSRange r = NSMakeRange(sql.length-1, 1);
[sql deleteCharactersInRange:r];
[sql appendFormat:@" where carname = '%@' and creatertime = '%@' ",carName,time];
//执行SQL语句
bool b = [db executeUpdate:sql withArgumentsInArray:dataArray];
[db close];
return b;
}else{
return NO;
}
}
3.查询
//查询验货记录 未提交、已提交、 根据单位id 查询所有不是预约状态的
+(NSArray *)selectCarInfoByState:(NSString *)state{
FMDatabase *db = [FMDatabase databaseWithPath:[FileOpretions filePath:KDBName]];
[db open];
NSString *sql = [NSString stringWithFormat:@"select * from LtCarInfo where state !='0' and deptid = '%@' order by state ,creatertime desc ",[UserDefaults objectForKey:@"deptId"]];
FMResultSet *resultSet = [db executeQuery:sql];
NSMutableArray *carInfoArray = [NSMutableArray array];
while ([resultSet next]) {
//将一条记录转换成字典
NSDictionary *dic = [resultSet resultDictionary];
NSMutableDictionary *statusDic = [NSMutableDictionary dictionary];
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([obj isKindOfClass:[NSNull class]]) {
}else if ([obj isKindOfClass:[NSData class]]) {
obj = [NSKeyedUnarchiver unarchiveObjectWithData:obj];
[statusDic setValue:obj forKey:key];
}else{
[statusDic setValue:obj forKey:key];
}
}];
CheLiangModel *carInfo = [[CheLiangModel alloc] initCheLiangByDic:statusDic];
[carInfoArray addObject:carInfo];
}
[db close];
return carInfoArray;
return nil;
4.删除
+ (BOOL)deleteHeiCar{
FMDatabase *db = [FMDatabase databaseWithPath:[FileOpretions filePath:KDBName]];
[db open];
NSString *sql = @"delete from LtHeiCar ";
BOOL b = [db executeUpdate:sql];
[db close];
return YES;
}
5.查询统计数目
//查询 本地 本单位当前预约数量
+(NSInteger)countChelingByDB{
NSInteger count = 0;
FMDatabase *db = [FMDatabase databaseWithPath:[FileOpretions filePath:KDBName]];
[db open];
NSString *sql = [NSString stringWithFormat:@"select COUNT(cid) from LtCarInfo where type = '1' and state = '0' and deptid = '%@'",[UserDefaults valueForKey:@"deptId"]] ;
FMResultSet *resultSet = [db executeQuery:sql];
if ([resultSet next]) {
count = [resultSet intForColumnIndex:0];
}
[db close];
return count;
}
二、CoreData
1.项目创建时勾选下方CoreData
2.如果项目创建时未勾选,但需要使用 下面链接有详细说明
3.如果引用第三方库 使用CoreData项目报错,一定要注意这个文件是否正确