交友:微信号 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. 简述arp协议的工作原理

    在每台安装有TCP/IP协议的电脑里都有一个ARP缓存表,表里的IP地址与MAC地址是一一对应的,如: 我们以主机A(192.168.1.5)向主机B(192.168.1.1)发送数据为例.当发送数据 ...

  2. [RK3288][Android6.0] 调试笔记 --- eMMC分区号和名字的对应【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/77318410 Platform: Rockchip OS: Android 6.0 Kern ...

  3. user版本如何永久性开启adb 的root权限【转】

    本文转载自:http://blog.csdn.net/o0daxu0o/article/details/52933926 [Solution]* adb 的root 权限是在system/core/a ...

  4. 关于Ajax实现的简单示例

    一.代码示例 关于Ajax的基本概念(包括XMLHttpRequest对象及其相关方法属性)移步这里(w3school中文版)学习了解. <!doctype html> <html ...

  5. innerText和innerHTML

    起因 由于公司的项目以前不考虑浏览器的兼容性问题,当时只考虑ie8浏览器,封装的控件也只针对ie8,我后面的做的时候,也就针对ie8,最近发现,封装的日期控件,在firefox竟然没法显示出来,去看J ...

  6. C/C++获取Linux系统CPU和内存及硬盘使用情况

    需求分析: 不使用Top  df  free 等命令,利用C/C++获取Linux系统CPU和内存及硬盘使用情况 实现: //通过获取/proc/stat (CPU)和/proc/meminfo(内存 ...

  7. pytest用例setup和teardown

    函数式以下两种: setup_function/teardown_function  每个用例开始和结束调用一次 setup_module/teardown_module     setup_modu ...

  8. ImportCommon

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using S ...

  9. Android开发--数据存储之File文件存储

    转载来自:http://blog.csdn.net/ahuier/article/details/10364757,并进行扩充 引言:Android开发中的数据存储方式 Android提供了5种方式存 ...

  10. java命令行从编译到打jar包到执行

     目录: 一. javac编译     1. 没有额外的jar包     2. 包含额外的jar包 二. jar打jar包 三. java运行     1. java命令执行     2. jar包执 ...