iOS本地数据库Sqlite(FMDB)及CoreData的使用

一、Sqlite(FMDB)

以前火狐有插件支持在线编辑sqlite文件,新版火狐不好用了,在前几篇文章中提到的有sqlte工具

https://blog.csdn.net/wangxiaoertedaye/article/details/87170016

下面是详细实现过程及代码,有需要的可以去下载整理好的文件该文件未引入FMDB包所以不能直接运行,复制代码至你的项目中使用,集成FMDB  1.手动下载FMDB包导入依赖库;2.使用pod管理第三方库,使用方法下述链接有详细说明

pod集成链接:https://blog.csdn.net/wangxiaoertedaye/article/details/82885790

下载地址:https://download.csdn.net/download/wangxiaoertedaye/11071638

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.如果项目创建时未勾选,但需要使用 下面链接有详细说明

https://www.cnblogs.com/xiangnizhidao/p/6029381.html

3.如果引用第三方库 使用CoreData项目报错,一定要注意这个文件是否正确

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值