交友:微信号 dwjluck2013

一、封装FMDB单例

(1)JLFMDBHelp.h文件

 #import <Foundation/Foundation.h>
#import <FMDatabase.h> @interface JLFMDBHelp : NSObject @property(nonatomic,strong)NSString *fileName;//数据库名 @property(nonatomic,strong)FMDatabase *database; //数据库对象 + (JLFMDBHelp*)sharedFMDBHelp;
//数据库存储路径
- (NSString*)dbPath;
//打开数据库
- (void)openDB;
//关闭数据库
- (void)closeDB;
//创建表
- (void)dbCreateTable;
//插入
-(BOOL)insertDBWithData:(NSData *)newsData dbWithString:(NSString *)channelWithStr;
//查询
-(NSMutableArray *)selectDBWithChannel:(NSString *)channel;
//给数据库命名
- (void)createDBWithName:(NSString*)dbName; //无返回结果集的操作
- (BOOL)notResultSetWithSql:(NSString*)sql;
//查询操作
- (NSArray*)qureyWithSql:(NSString*)sql;
@end

(2)JLFMDBHelp.m文件

 #import "JLFMDBHelp.h"
#import "JLMainViewsModel.h" @interface JLFMDBHelp() @end @implementation JLFMDBHelp + (JLFMDBHelp*)sharedFMDBHelp {
static JLFMDBHelp *help = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
help = [[JLFMDBHelp alloc] init];
});
return help;
} #pragma amrk - 根据名称创建沙盒路径用来保存数据库文件
- (NSString*)dbPath {
//说明fileName不为空
if (self.fileName.length) {
//1.创建DB,路径
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [documents stringByAppendingPathComponent:@"channelNews.db"];
return filePath;
} else {
return @"";
}
} #pragma mark - 让用户来命名数据库的名称
- (void)createDBWithName:(NSString*)dbName {
if (dbName.length == ) {
//是防止用户直接传值为nil 或者 NULL
self.fileName = @"";
}else{
self.fileName = [dbName stringByAppendingString:@".db"];
}
} #pragma mark - 创建数据库对象
//懒加载
- (FMDatabase*)database {
if (!_database) {
_database = [FMDatabase databaseWithPath:[self dbPath]];
}
return _database;
}
#pragma mark - 判断是否存在表
- (BOOL) isTableOK:(NSString *)tableName
{
NSString *sqlStr = [NSString stringWithFormat:@"select count(*) as 'count' from sqlite_master where type ='table' and tbl_name = '%@';",tableName];
FMResultSet *rs = [self.database executeQuery:sqlStr];
while ([rs next])
{
NSInteger count = [rs intForColumn:@"count"];
NSLog(@"isTableOK %ld", (long)count); if ( == count)
{
return NO;
}
else
{
return YES;
}
}
return NO;
}
#pragma mark - 创建数据库表
- (void)dbCreateTable {
if([self.database open]){
if (![self isTableOK:@"t_newsWithChannel"]) {
NSString *sql = @"create table if not exists t_newsWithChannel (newsID integer primary key autoincrement,nwesName blob,newsType VARCHAR not null);";
BOOL execResult = [self.database executeUpdate:sql];
if(execResult){
NSLog(@"table ok");
}else{
NSLog(@"table fail");
}
}
[self closeDB];
}else{
NSLog(@"open fail");
}
} #pragma mark - 打开数据库的方法
- (void)openDB {
BOOL isOpen = [self.database open];
if (isOpen) {
NSLog(@"打开数据库成功");
} else {
NSLog(@"打开数据库失败");
}
} #pragma mark - 关闭数据库的方法
- (void)closeDB {
BOOL isClose = [self.database close];
if (isClose) {
NSLog(@"关闭数据库成功");
} else {
NSLog(@"关闭数据库失败");
}
}
//插入
-(BOOL)insertDBWithData:(NSData *)newsData dbWithString:(NSString *)channelWithStr{
[self.database open];
NSString *sql = [NSString stringWithFormat:@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)"];
BOOL execResult = [self.database executeUpdate:sql,newsData,channelWithStr];
if(execResult){
NSLog(@"insert ok");
return YES;
}else{
NSLog(@"insert fail");
return NO;
}
}
//查询
-(NSMutableArray *)selectDBWithChannel:(NSString *)channel{
NSString *resultSql = [NSString stringWithFormat:@"select * from t_newsWithChannel where newsType = '%@'",channel];
FMResultSet *set = [self.database executeQuery:resultSql];
NSMutableArray *array = [NSMutableArray array];
while ([set next]) {
NSData *newsData = [set dataForColumn:@"nwesName"];
JLMainViewsModel *model = [NSKeyedUnarchiver unarchiveObjectWithData:newsData];
if (model) {
[array addObject:model];
}
}
return array;
}
@end

二、模型数据

(1)JLMainViewsModel.h文件

要遵守协议

@interface JLMainViewsModel : NSObject<NSCopying,NSCoding>

(2)JLMainViewsModel.m文件

 -(void)encodeWithCoder:(NSCoder *)aCoder{

     [aCoder encodeObject:self.fromSource forKey:@"fromSource"];
[aCoder encodeObject:self.url forKey:@"url"];
[aCoder encodeObject:self.title forKey:@"title"];
[aCoder encodeObject:self.type forKey:@"type"];
[aCoder encodeObject:self.newsTime forKey:@"newsTime"];
[aCoder encodeObject:self.imageUrl forKey:@"imageUrl"];
[aCoder encodeObject:self.imageArray forKey:@"imageArray"];
[aCoder encodeObject:self.bigImageUrl forKey:@"bigImageUrl"];
[aCoder encodeObject:self.bigImageArray forKey:@"bigImageArray"];
[aCoder encodeObject:self.recommend forKey:@"recommend"];
[aCoder encodeObject:self.exData forKey:@"exData"];
[aCoder encodeObject:self.newsType forKey:@"newsType"];
[aCoder encodeObject:self.style forKey:@"style"];
[aCoder encodeObject:self.gzh forKey:@"gzh"];
[aCoder encodeObject:self.uniqId forKey:@"uniqId"];
[aCoder encodeObject:self.subdesc forKey:@"subdesc"];
[aCoder encodeObject:self.autoplay forKey:@"autoplay"];
[aCoder encodeObject:self.fromicon forKey:@"fromicon"];
[aCoder encodeObject:self.webUrl forKey:@"webUrl"];
} -(id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.fromSource = [aDecoder decodeObjectForKey:@"fromSource"];
self.url = [aDecoder decodeObjectForKey:@"url"];
self.title = [aDecoder decodeObjectForKey:@"title"];
self.type = [aDecoder decodeObjectForKey:@"type"];
self.newsTime = [aDecoder decodeObjectForKey:@"newsTime"];
self.imageUrl = [aDecoder decodeObjectForKey:@"imageUrl"];
self.imageArray = [aDecoder decodeObjectForKey:@"imageArray"];
self.bigImageUrl = [aDecoder decodeObjectForKey:@"bigImageUrl"];
self.bigImageArray = [aDecoder decodeObjectForKey:@"bigImageArray"];
self.recommend = [aDecoder decodeObjectForKey:@"recommend"];
self.exData = [aDecoder decodeObjectForKey:@"exData"];
self.newsType = [aDecoder decodeObjectForKey:@"newsType"];
self.style = [aDecoder decodeObjectForKey:@"style"];
self.gzh = [aDecoder decodeObjectForKey:@"gzh"];
self.uniqId = [aDecoder decodeObjectForKey:@"uniqId"];
self.subdesc = [aDecoder decodeObjectForKey:@"subdesc"];
self.autoplay = [aDecoder decodeObjectForKey:@"autoplay"];
self.fromicon = [aDecoder decodeObjectForKey:@"fromicon"];
self.webUrl = [aDecoder decodeObjectForKey:@"webUrl"];
}
return self;
} - (id)copyWithZone:(NSZone *)zone
{
JLMainViewsModel *model = [[[self class] allocWithZone:zone]init];
return model;
}

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

 //网络请求回调 成功
if(successBlock){
JLFMDBHelp *fmdbHelp = [JLFMDBHelp sharedFMDBHelp];
//数据库名
[fmdbHelp createDBWithName:@"t_newsWithChannel"];
//路径
NSString *filePath = [fmdbHelp dbPath];
//创建数据库表
[fmdbHelp dbCreateTable]; FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:filePath];
[queue inDatabase:^(FMDatabase *db) {
[mArray enumerateObjectsUsingBlock:^(JLMainViewsModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//将数组转换成字符串
NSData *newsData = [NSKeyedArchiver archivedDataWithRootObject:obj];
//插入
if ([fmdbHelp insertDBWithData:newsData dbWithString:chanl]) {
[fmdbHelp closeDB];
}else{
[fmdbHelp closeDB];
}
}];
}]; // //1.获取存储的路径
// NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// NSString *filePatha = [documents stringByAppendingPathComponent:@"newsModelWithArray.plist"];
// //归档
// [NSKeyedArchiver archiveRootObject:mArray toFile:filePatha];
// NSLog(@"路径-----%@",filePath);
successBlock(mArray.copy);
}

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

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

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

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

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

FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符的更多相关文章

  1. 并发编程学习笔记之Java存储模型(十三)

    概述 Java存储模型(JMM),安全发布.规约,同步策略等等的安全性得益于JMM,在你理解了为什么这些机制会如此工作后,可以更容易有效地使用它们. 1. 什么是存储模型,要它何用. 如果缺少同步,就 ...

  2. LSM树存储模型

    ----<大规模分布式存储系统:原理解析与架构实战>读书笔记 之前研究了Bitcask存储模型,今天来看看LSM存储模型,两者尽管同属于基于键值的日志型存储模型.可是Bitcask使用哈希 ...

  3. Hash存储模型、B-Tree存储模型、LSM存储模型介绍

    每一种数据存储系统,对应有一种存储模型,或者叫存储引擎.我们今天要介绍的是三种比较流行的存储模型,分别是: Hash存储模型 B-Tree存储模型 LSM存储模型 不同存储模型的应用情况 1.Hash ...

  4. Python3编写网络爬虫11-数据存储方式四-关系型数据库存储

    关系型数据库存储 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表保存的,所以它的存储方式就是行列组成的表.每一列是一个字段,每一行是一条记录.表可以看作某个实体的集合,而实体之间存在联系, ...

  5. 数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)

    背景 公司有一个数据处理线,上面的数据经过不同环境处理,然后上线到正式库.其中一个环节需要将数据进行处理然后导入到另外一个库(Sql Server).这个处理的程序是老大用python写的,处理完后进 ...

  6. DAOS 分布式异步对象存储|存储模型

    概述 DAOS Pool 是分布在 Target 集合上的存储资源预留.分配给每个 Target 上的 Pool 的实际空间称为 Pool Shard. 分配给 Pool 的总空间在创建时确定,后期可 ...

  7. iOS数据存储之对象归档

    iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...

  8. SQLite剖析之存储模型

    前言 SQLite作为嵌入式数据库,通常针对的应用的数据量相对于DBMS的数据量小.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这 ...

  9. SQLite入门与分析(八)---存储模型(1)

    写在前面:SQLite作为嵌入式数据库,通常针对的应用的数据量相对于通常DBMS的数据量是较小的.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树 ...

随机推荐

  1. Jpa生成mysql注释,添加ODBC数据源导入数据到EA

    通过Jpa 注解生成表注释 实体类中使用如下注解,生成表字段注释: @Column(name = "userid", columnDefinition = "varcha ...

  2. 常用的PHP类库,PHP开发者必备【转】

    PHP开发者常用的PHP类库和组件 PDF 生成器 FPDF - 这量一个可以让你生成PDF的纯PHP类库. Excel 相关 你的站点需要生成Excel?没有问题,下面这两个类库可以让你轻松做到这一 ...

  3. 关于URL编码的一些结论

    转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html与http://www.ruanyifeng.com/blog/2007/10/ ...

  4. cowboy跨域请求处理

    这几日在使用cowboy开发https服务器的过程中碰到几个问题,这里随手记录一下. 1)如果返回错误ERR_EMPTY_RESPONSE,那么可能是web服务器被关闭了. 2)如果返回错误ERR_C ...

  5. 「UVA10298」 Power Strings(KMP

    题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 复制 abcd aaaa ababab . 输出样例#1: 复制 1 4 3 题解 Luogu的题解 这里是对目前 ...

  6. HTTP Status 500 - Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

    如果在service类上面没有添加注解,出现异常 @Transactional

  7. C++之运算符重载(前置++和后置++)

    今天在阅读<google c++ 编程风格>的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理 ...

  8. POJ1742(多重部分和问题:模板题)

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 32776   Accepted: 11131 Descripti ...

  9. 使用tableview的表头button 实现多 cell 的选择

    首先声明本篇博文是作者原创,在QQ群里看到一枚猿友求助,问题描述:使用UItableView 实现在表头里点击不同的按钮,去刷新当前的界面(界面是大的 cell),自己就实现了一下. 实验原材料:故事 ...

  10. force

    题意 求解 Ei = Fi/qi 解法: 方法一: 考虑左侧的式子,直接多项式乘法. 对于右面的式子,我们记做$B_j$,这样有 $$B_j = \sum_{j<i}{ revq_{n-i} f ...