交友:微信号 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. Machine Learning in Action(2) 决策树算法

    决策树也是有监督机器学习方法. 电影<无耻混蛋>里有一幕游戏,在德军小酒馆里有几个人在玩20问题游戏,游戏规则是一个设迷者在纸牌中抽出一个目标(可以是人,也可以是物),而猜谜者可以提问题, ...

  2. Java其实不支持垃圾回收

    Java其实不支持垃圾回收.如果真的支持的话,大多数Java程序在运行的一开始就应该把程序本身删除,因为这些程序本身就是垃圾.   // TODO: This is a 分割线. Please no ...

  3. java多线程-多线程常识

    线程和进程的区别是什么?进程是一个正在运行的软件程序,打开资源管理器可以看到好多正在运行的进程,而线程则是程序中的顺序控制流,只能使用分配给程序的资源和环境.一个进程至少存在一个线程(主线程). 在j ...

  4. 自动化测试框架selenium+java+TestNG——读取csv文件

    读取csv文件可以直接读取,也可以使用javacsv.jar,后者比较简单,这个也可以变相认为是对表格的处理,我们可以在表格中做好数据,存储成csv格式的文件,后续对xlsx表格的操作抽个时间再记录下 ...

  5. struts2 小例子(教训篇)

    学了一阵子的struts2了,到了最后,想自己写个小程序,发现最简单的配置文件都 竟然能弄错,是我这几天睡眠不足么.怎么可能,爱好这门的,怎么会这样.这样真的很伤心啊.小小心灵受不了这种打击啊.... ...

  6. 当数据库中的字段与javabean中对应的属性名不同

    当数据库中的字段与javabean中对应的属性名不同时: 在查询语句中对不同的字段起别名,例如: 数据库中的字段名为last_name , javabean中为lastName则:select las ...

  7. C++之const类成员变量,const成员函数

    const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...

  8. Java使用Jacob转换Word为HTML

    从今天开始,我也要养成记录开发中遇到的问题和解决方法的好习惯! 最近开发一个Android项目,需要用到查看Word和Pdf文档的功能,由于Android没有直接显示Word和PDF文档的组件,只有一 ...

  9. FFmpeg常用命令 (三)流媒体

    前言 如此强大的FFmpeg,能够实现视频采集.视频格式转化.视频截图.视频添加水印.视频切片.视频录制.视频推流.更改音视频参数功能等.通过终端命令如何实现这些功能,Richy在本文做一记录,以备之 ...

  10. zookeeper分布式安装

    1.先把zookeeper-3.5.2-alpha.tar上传解压到/usr/local/下重命名为zookeeper ############# zookeeper env ############ ...