FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符
交友:微信号 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 (?,?)")一定要用占位符的更多相关文章
- 并发编程学习笔记之Java存储模型(十三)
概述 Java存储模型(JMM),安全发布.规约,同步策略等等的安全性得益于JMM,在你理解了为什么这些机制会如此工作后,可以更容易有效地使用它们. 1. 什么是存储模型,要它何用. 如果缺少同步,就 ...
- LSM树存储模型
----<大规模分布式存储系统:原理解析与架构实战>读书笔记 之前研究了Bitcask存储模型,今天来看看LSM存储模型,两者尽管同属于基于键值的日志型存储模型.可是Bitcask使用哈希 ...
- Hash存储模型、B-Tree存储模型、LSM存储模型介绍
每一种数据存储系统,对应有一种存储模型,或者叫存储引擎.我们今天要介绍的是三种比较流行的存储模型,分别是: Hash存储模型 B-Tree存储模型 LSM存储模型 不同存储模型的应用情况 1.Hash ...
- Python3编写网络爬虫11-数据存储方式四-关系型数据库存储
关系型数据库存储 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表保存的,所以它的存储方式就是行列组成的表.每一列是一个字段,每一行是一条记录.表可以看作某个实体的集合,而实体之间存在联系, ...
- 数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)
背景 公司有一个数据处理线,上面的数据经过不同环境处理,然后上线到正式库.其中一个环节需要将数据进行处理然后导入到另外一个库(Sql Server).这个处理的程序是老大用python写的,处理完后进 ...
- DAOS 分布式异步对象存储|存储模型
概述 DAOS Pool 是分布在 Target 集合上的存储资源预留.分配给每个 Target 上的 Pool 的实际空间称为 Pool Shard. 分配给 Pool 的总空间在创建时确定,后期可 ...
- iOS数据存储之对象归档
iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...
- SQLite剖析之存储模型
前言 SQLite作为嵌入式数据库,通常针对的应用的数据量相对于DBMS的数据量小.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这 ...
- SQLite入门与分析(八)---存储模型(1)
写在前面:SQLite作为嵌入式数据库,通常针对的应用的数据量相对于通常DBMS的数据量是较小的.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树 ...
随机推荐
- 谷歌浏览器使用SelectorGadget和Xpath Helper获取xpath和css path
在上篇文章里,介绍了如何在火狐浏览器中获取网页元素的xpath和css path. 这篇文章将介绍,在谷歌浏览器中使用SelectorGadget和Xpath Helper实现同样功能. 这两个谷歌浏 ...
- GCD 开启一个定时器实现倒计时功能
UIAlertView * alt = [[UIAlertView alloc] initWithTitle:@"提示" message:@"操作成功,马上返回继续体验吧 ...
- poj3349 Snowflake Snow Snowflakes —— 哈希表
题目链接:http://poj.org/problem?id=3349 题意:雪花有6个瓣,有n个雪花,输入每个雪花的瓣长,判断是否有一模一样的雪花(通过旋转或翻转最终一样,即瓣长对应相等).如果前面 ...
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...
- 扩散(diffusion)和弥散(dispersion)有什么区别
作者:谢易正链接:https://www.zhihu.com/question/23914350/answer/177359196来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- html5--3.22 综合实例03
html5--3.22 综合实例03 学习要点 通过一个综合实例来回顾学过的内容 这一章的内容比较多,不必强求一下子全记住,多做一些练习,用得多了自然就可以记住了 可以自己找一些实例练练手,比如各网站 ...
- linux应用之tomcat的安装及配置(centos)
CentOS 6.6下安装配置Tomcat环境 [日期:2015-08-25] 来源:Linux社区 作者:tae44 [字体:大 中 小] 实验系统:CentOS 6.6_x86_64 实验前 ...
- 51nod-1065:最小正子段和(STL)
N个整数组成的序列a11,a22,a33,…,ann,从中选出一个子序列(aii,ai+1i+1,…ajj),使这个子序列的和>0,并且这个和是所有和>0的子序列中最小的. 例如:4,-1 ...
- Unix高级环境编程
[07] Unix进程环境==================================1. 进程终止 atexit()函数注册终止处理程序. exit()或return语句: ...
- bzoj 1014 [JSOI2008]火星人prefix——splay+哈希
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...