zoukankan      html  css  js  c++  java
  • FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符

    交友:微信号 dwjluck2013

    一、封装FMDB单例

    (1)JLFMDBHelp.h文件

     1 #import <Foundation/Foundation.h>
     2 #import <FMDatabase.h>
     3 
     4 @interface JLFMDBHelp : NSObject
     5 
     6 @property(nonatomic,strong)NSString *fileName;//数据库名
     7 
     8 @property(nonatomic,strong)FMDatabase *database; //数据库对象
     9 
    10 + (JLFMDBHelp*)sharedFMDBHelp;
    11 //数据库存储路径
    12 - (NSString*)dbPath;
    13 //打开数据库
    14 - (void)openDB;
    15 //关闭数据库
    16 - (void)closeDB;
    17 //创建表
    18 - (void)dbCreateTable;
    19 //插入
    20 -(BOOL)insertDBWithData:(NSData *)newsData dbWithString:(NSString *)channelWithStr;
    21 //查询
    22 -(NSMutableArray *)selectDBWithChannel:(NSString *)channel;
    23 //给数据库命名
    24 - (void)createDBWithName:(NSString*)dbName;
    25 
    26 //无返回结果集的操作
    27 - (BOOL)notResultSetWithSql:(NSString*)sql;
    28 //查询操作
    29 - (NSArray*)qureyWithSql:(NSString*)sql;
    30 @end

    (2)JLFMDBHelp.m文件

      1 #import "JLFMDBHelp.h"
      2 #import "JLMainViewsModel.h"
      3 
      4 @interface JLFMDBHelp()
      5 
      6 @end
      7 
      8 @implementation JLFMDBHelp
      9 
     10 + (JLFMDBHelp*)sharedFMDBHelp {
     11     static JLFMDBHelp *help = nil;
     12     static dispatch_once_t onceToken;
     13     dispatch_once(&onceToken, ^{
     14         help = [[JLFMDBHelp alloc] init];
     15     });
     16     return help;
     17 }
     18 
     19 #pragma amrk - 根据名称创建沙盒路径用来保存数据库文件
     20 - (NSString*)dbPath {
     21     //说明fileName不为空
     22     if (self.fileName.length) {
     23         //1.创建DB,路径
     24         NSString *documents = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
     25         NSString *filePath = [documents stringByAppendingPathComponent:@"channelNews.db"];
     26         return filePath;
     27     } else {
     28         return @"";
     29     }
     30 }
     31 
     32 #pragma mark - 让用户来命名数据库的名称
     33 - (void)createDBWithName:(NSString*)dbName {
     34     if (dbName.length == 0) {
     35         //是防止用户直接传值为nil 或者 NULL
     36         self.fileName = @"";
     37     }else{
     38         self.fileName = [dbName stringByAppendingString:@".db"];
     39     }
     40 }
     41 
     42 #pragma mark - 创建数据库对象
     43 //懒加载
     44 - (FMDatabase*)database {
     45     if (!_database) {
     46         _database = [FMDatabase databaseWithPath:[self dbPath]];
     47     }
     48     return _database;
     49 }
     50 #pragma mark - 判断是否存在表
     51 - (BOOL) isTableOK:(NSString *)tableName
     52 {
     53     NSString *sqlStr = [NSString stringWithFormat:@"select count(*) as 'count' from sqlite_master where type ='table' and tbl_name = '%@';",tableName];
     54     FMResultSet *rs = [self.database executeQuery:sqlStr];
     55     while ([rs next])
     56     {
     57         NSInteger count = [rs intForColumn:@"count"];
     58         NSLog(@"isTableOK %ld", (long)count);
     59         
     60         if (0 == count)
     61         {
     62             return NO;
     63         }
     64         else
     65         {
     66             return YES;
     67         }
     68     }
     69     return NO;
     70 }
     71 #pragma mark - 创建数据库表
     72 - (void)dbCreateTable {
     73     if([self.database open]){
     74         if (![self isTableOK:@"t_newsWithChannel"]) {
     75             NSString *sql = @"create table if not exists t_newsWithChannel (newsID integer primary key autoincrement,nwesName blob,newsType VARCHAR not null);";
     76             BOOL execResult = [self.database executeUpdate:sql];
     77             if(execResult){
     78                 NSLog(@"table ok");
     79             }else{
     80                 NSLog(@"table fail");
     81             }
     82         }
     83         [self closeDB];
     84     }else{
     85         NSLog(@"open fail");
     86     }
     87 }
     88 
     89 #pragma mark - 打开数据库的方法
     90 - (void)openDB {
     91     BOOL isOpen = [self.database open];
     92     if (isOpen) {
     93         NSLog(@"打开数据库成功");
     94     } else {
     95         NSLog(@"打开数据库失败");
     96     }
     97 }
     98 
     99 #pragma mark - 关闭数据库的方法
    100 - (void)closeDB {
    101     BOOL isClose = [self.database close];
    102     if (isClose) {
    103         NSLog(@"关闭数据库成功");
    104     } else {
    105         NSLog(@"关闭数据库失败");
    106     }
    107 }
    108 //插入
    109 -(BOOL)insertDBWithData:(NSData *)newsData dbWithString:(NSString *)channelWithStr{
    110     [self.database open];
    111     NSString *sql = [NSString stringWithFormat:@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)"];
    112     BOOL execResult = [self.database executeUpdate:sql,newsData,channelWithStr];
    113     if(execResult){
    114         NSLog(@"insert ok");
    115         return YES;
    116     }else{
    117         NSLog(@"insert fail");
    118         return NO;
    119     }
    120 }
    121 //查询
    122 -(NSMutableArray *)selectDBWithChannel:(NSString *)channel{
    123     NSString *resultSql = [NSString stringWithFormat:@"select * from t_newsWithChannel where newsType = '%@'",channel];
    124     FMResultSet *set = [self.database executeQuery:resultSql];
    125     NSMutableArray *array = [NSMutableArray array];
    126     while ([set next]) {
    127         NSData *newsData = [set dataForColumn:@"nwesName"];
    128         JLMainViewsModel *model = [NSKeyedUnarchiver unarchiveObjectWithData:newsData];
    129         if (model) {
    130             [array addObject:model];
    131         }
    132     }
    133     return array;
    134 }
    135 @end

    二、模型数据

    (1)JLMainViewsModel.h文件

    要遵守协议

    @interface JLMainViewsModel : NSObject<NSCopying,NSCoding>

    (2)JLMainViewsModel.m文件

     1 -(void)encodeWithCoder:(NSCoder *)aCoder{
     2     
     3     [aCoder encodeObject:self.fromSource forKey:@"fromSource"];
     4     [aCoder encodeObject:self.url forKey:@"url"];
     5     [aCoder encodeObject:self.title forKey:@"title"];
     6     [aCoder encodeObject:self.type forKey:@"type"];
     7     [aCoder encodeObject:self.newsTime forKey:@"newsTime"];
     8     [aCoder encodeObject:self.imageUrl forKey:@"imageUrl"];
     9     [aCoder encodeObject:self.imageArray forKey:@"imageArray"];
    10     [aCoder encodeObject:self.bigImageUrl forKey:@"bigImageUrl"];
    11     [aCoder encodeObject:self.bigImageArray forKey:@"bigImageArray"];
    12     [aCoder encodeObject:self.recommend forKey:@"recommend"];
    13     [aCoder encodeObject:self.exData forKey:@"exData"];
    14     [aCoder encodeObject:self.newsType forKey:@"newsType"];
    15     [aCoder encodeObject:self.style forKey:@"style"];
    16     [aCoder encodeObject:self.gzh forKey:@"gzh"];
    17     [aCoder encodeObject:self.uniqId forKey:@"uniqId"];
    18     [aCoder encodeObject:self.subdesc forKey:@"subdesc"];
    19     [aCoder encodeObject:self.autoplay forKey:@"autoplay"];
    20     [aCoder encodeObject:self.fromicon forKey:@"fromicon"];
    21     [aCoder encodeObject:self.webUrl forKey:@"webUrl"];
    22 }
    23 
    24 -(id)initWithCoder:(NSCoder *)aDecoder{
    25     if (self = [super init]) {
    26         self.fromSource = [aDecoder decodeObjectForKey:@"fromSource"];
    27         self.url = [aDecoder decodeObjectForKey:@"url"];
    28         self.title = [aDecoder decodeObjectForKey:@"title"];
    29         self.type = [aDecoder decodeObjectForKey:@"type"];
    30         self.newsTime = [aDecoder decodeObjectForKey:@"newsTime"];
    31         self.imageUrl = [aDecoder decodeObjectForKey:@"imageUrl"];
    32         self.imageArray = [aDecoder decodeObjectForKey:@"imageArray"];
    33         self.bigImageUrl = [aDecoder decodeObjectForKey:@"bigImageUrl"];
    34         self.bigImageArray = [aDecoder decodeObjectForKey:@"bigImageArray"];
    35         self.recommend = [aDecoder decodeObjectForKey:@"recommend"];
    36         self.exData = [aDecoder decodeObjectForKey:@"exData"];
    37         self.newsType = [aDecoder decodeObjectForKey:@"newsType"];
    38         self.style = [aDecoder decodeObjectForKey:@"style"];
    39         self.gzh = [aDecoder decodeObjectForKey:@"gzh"];
    40         self.uniqId = [aDecoder decodeObjectForKey:@"uniqId"];
    41         self.subdesc = [aDecoder decodeObjectForKey:@"subdesc"];
    42         self.autoplay = [aDecoder decodeObjectForKey:@"autoplay"];
    43         self.fromicon = [aDecoder decodeObjectForKey:@"fromicon"];
    44         self.webUrl = [aDecoder decodeObjectForKey:@"webUrl"];
    45     }
    46     return self;
    47 }
    48 
    49 - (id)copyWithZone:(NSZone *)zone
    50 {
    51     JLMainViewsModel *model = [[[self class] allocWithZone:zone]init];
    52     return model;
    53 }

    三、存储数据  在网络请求成功后存储  只是存储时的代码

     1 //网络请求回调 成功
     2                 if(successBlock){
     3                     JLFMDBHelp *fmdbHelp = [JLFMDBHelp sharedFMDBHelp];
     4                     //数据库名
     5                     [fmdbHelp createDBWithName:@"t_newsWithChannel"];
     6                     //路径
     7                     NSString *filePath = [fmdbHelp dbPath];
     8                     //创建数据库表
     9                     [fmdbHelp dbCreateTable];
    10                     
    11                     FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:filePath];
    12                     [queue inDatabase:^(FMDatabase *db) {
    13                         [mArray enumerateObjectsUsingBlock:^(JLMainViewsModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    14                             //将数组转换成字符串
    15                             NSData *newsData = [NSKeyedArchiver archivedDataWithRootObject:obj];
    16                             //插入
    17                             if ([fmdbHelp insertDBWithData:newsData dbWithString:chanl]) {
    18                                 [fmdbHelp closeDB];
    19                             }else{
    20                                 [fmdbHelp closeDB];
    21                             }
    22                         }];
    23                     }];
    24 
    25                     
    26 //                    //1.获取存储的路径
    27 //                    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    28 //                    NSString *filePatha = [documents stringByAppendingPathComponent:@"newsModelWithArray.plist"];
    29 //                    //归档
    30 //                    [NSKeyedArchiver archiveRootObject:mArray toFile:filePatha];
    31 //                    NSLog(@"路径-----%@",filePath);
    32                     successBlock(mArray.copy);
    33                 }

    四、在需要用的vc中读取数据

     1 #pragma mark - 本地数据库中读取数据(模型对象)
     2 -(void)getdbDataSource{
     3     JLFMDBHelp *fmdbHelp = [JLFMDBHelp sharedFMDBHelp];
     4     //数据库名
     5     [fmdbHelp createDBWithName:@"channelNews"];
     6     //打开数据库
     7     [fmdbHelp openDB];
     8     
     9     NSMutableArray *mNewsArray = [fmdbHelp selectDBWithChannel:self.newsType];
    10     NSLog(@"%@",mNewsArray);
    11 }

    重点:遇到的坑,存储数据的时候

    NSString *sql = [NSString stringWithFormat:@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)"];
    values (?,?) 这里一定要用占位符,不能用values (%@,%@) 否则存储看不出问题,存储的数据却不对,反序列化的时候不会走model中的

    -(id)initWithCoder:(NSCoder *)aDecoder方法

  • 相关阅读:
    装饰者模式【结构模式】
    代理模式【结构模式】
    原型模式【构建模式】
    建造者模式【构建模式】
    抽象工厂模式【构建模式】
    工厂模式【构建模式】
    单例模式【构建模式】
    设计原则
    Collector 源码分析
    Maven 包命令
  • 原文地址:https://www.cnblogs.com/dujiahong/p/6634131.html
Copyright © 2011-2022 走看看