iOS中 学会如何对sqlite3 进行封装 (纯手工)
#waring ---(看官注意) ---使用说明:
①在创建自定义model类之前让该类继承自文件中的Model类,
②为model类选一个NSString属性作为主键:(既,在初始化方法里面将从父类Model类
ID属性等于你所选的NSString属性值即可 (具体可参见.下文 二.3 中)
一.文件夹结构:
二.文件说明:
1.NSObject+NSCoding
该文件是对对象类型进行encoding 以及 decoding操作的方法
2.DataHandle
1. 该文件是 sqlite3 单例数据库对Model 对象进行增.删.查.改
3.Model文件夹下面的Model 是遵守NSCoding 协议的底层Model
1. 而Model文件夹下面的TestModel 则是继承自Model 的一种自定义model (也就是我们项目中的自定义的Model),
2.如此,我们自己项目中的自定义model 只要继承字Model 类就可以了,
3.但还要在自定义的TestModel中添加以下改动: self.ID属性是从父类Model中继承来的 而Model 的ID属性被设置为数据库的主键, 因此不可以为空,需要将TestModel的一个属性替代ID属性,既作为主键;
三.各个文件的代码示例
1.NSObject+NSCoding
.h文件
.m文件
#import "NSObject+NSCoding.h"
#import <objc/runtime.h>
#import <UIKit/UIKit.h>
@implementation NSObject (NSCoding)
- (NSMutableDictionary *)propertiesForClass:(Class)klass {
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
unsigned int outCount, i;
//通过运行时获取 该类所有属性列表
objc_property_t *properties = class_copyPropertyList(klass, &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *pname = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
NSString *pattrs = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];
pattrs = [[pattrs componentsSeparatedByString:@","] objectAtIndex:0];
pattrs = [pattrs substringFromIndex:1];
[results setObject:pattrs forKey:pname];
}
free(properties);
if ([klass superclass] != [NSObject class]) {
[results addEntriesFromDictionary:[self propertiesForClass:[klass superclass]]];
}
return results;
}
- (NSDictionary *)properties {
return [self propertiesForClass:[self class]];
}
- (void)autoEncodeWithCoder:(NSCoder *)coder {
NSDictionary *properties = [self properties];
for (NSString *key in properties) {
NSString *type = [properties objectForKey:key];
id value;
unsigned long long ullValue;
BOOL boolValue;
float floatValue;
double doubleValue;
NSInteger intValue;
unsigned long ulValue;
long longValue;
unsigned unsignedValue;
short shortValue;
NSString *className;
NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(key)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:NSSelectorFromString(key)];
[invocation setTarget:self];
switch ([type characterAtIndex:0]){
case '@': // object
if ([[type componentsSeparatedByString:@"\""] count] > 1) {
className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1];
Class class = NSClassFromString(className);
#warning UIImage类型的属性不归档 add by yhy›
if ([className isEqualToString:@"UIImage"]) {
//如果属性是UIImage类型的,不进行归档
break;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
value = [self performSelector:NSSelectorFromString(key)];
#pragma clang diagnostic pop
// only decode if the property conforms to NSCoding
if([class conformsToProtocol:@protocol(NSCoding)]){
[coder encodeObject:value forKey:key];
}
}
break;
case 'c': // bool
[invocation invoke];
[invocation getReturnValue:&boolValue];
[coder encodeObject:[NSNumber numberWithBool:boolValue] forKey:key];
break;
case 'f': // float
[invocation invoke];
[invocation getReturnValue:&floatValue];
[coder encodeObject:[NSNumber numberWithFloat:floatValue] forKey:key];
break;
case 'd': // double
[invocation invoke];
[invocation getReturnValue:&doubleValue];
[coder encodeObject:[NSNumber numberWithDouble:doubleValue] forKey:key];
break;
case 'i': // int
[invocation invoke];
[invocation getReturnValue:&intValue];
[coder encodeObject:[NSNumber numberWithInt:(int)intValue] forKey:key];
break;
case 'L': // unsigned long
[invocation invoke];
[invocation getReturnValue:&ulValue];
[coder encodeObject:[NSNumber numberWithUnsignedLong:ulValue] forKey:key];
break;
case 'Q': // unsigned long long
[invocation invoke];
[invocation getReturnValue:&ullValue];
[coder encodeObject:[NSNumber numberWithUnsignedLongLong:ullValue] forKey:key];
break;
case 'l': // long
[invocation invoke];
[invocation getReturnValue:&longValue];
[coder encodeObject:[NSNumber numberWithLong:longValue] forKey:key];
break;
case 's': // short
[invocation invoke];
[invocation getReturnValue:&shortValue];
[coder encodeObject:[NSNumber numberWithShort:shortValue] forKey:key];
break;
case 'I': // unsigned
[invocation invoke];
[invocation getReturnValue:&unsignedValue];
[coder encodeObject:[NSNumber numberWithUnsignedInt:unsignedValue] forKey:key];
break;
default:
break;
}
}
}
- (void)autoDecode:(NSCoder *)coder {
NSDictionary *properties = [self properties];
for (NSString *key in properties) {
NSString *type = [properties objectForKey:key];
id value;
NSNumber *number;
NSInteger i;
CGFloat f;
BOOL b;
double d;
unsigned long ul;
unsigned long long ull;
long longValue;
unsigned unsignedValue;
short shortValue;
NSString *className;
switch ([type characterAtIndex:0]) {
case '@': // object
if ([[type componentsSeparatedByString:@"\""] count] > 1) {
className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1];
Class class = NSClassFromString(className);
#warning UIImage类型的属性不归档 add by yhy
if ([className isEqualToString:@"UIImage"]) {
//如果属性是UIImage类型的,不进行反归档
break;
}
// only decode if the property conforms to NSCoding
if ([class conformsToProtocol:@protocol(NSCoding )]){
value = [coder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
}
break;
case 'c': // bool
number = [coder decodeObjectForKey:key];
b = [number boolValue];
[self setValue:@(b) forKey:key];
break;
case 'f': // float
number = [coder decodeObjectForKey:key];
f = [number floatValue];
[self setValue:@(f) forKey:key];
break;
case 'd': // double
number = [coder decodeObjectForKey:key];
d = [number doubleValue];
[self setValue:@(d) forKey:key];
break;
case 'i': // int
number = [coder decodeObjectForKey:key];
i = [number intValue];
[self setValue:@(i) forKey:key];
break;
case 'L': // unsigned long
number = [coder decodeObjectForKey:key];
ul = [number unsignedLongValue];
[self setValue:@(ul) forKey:key];
break;
case 'Q': // unsigned long long
number = [coder decodeObjectForKey:key];
ull = [number unsignedLongLongValue];
[self setValue:@(ull) forKey:key];
break;
case 'l': // long
number = [coder decodeObjectForKey:key];
longValue = [number longValue];
[self setValue:@(longValue) forKey:key];
break;
case 'I': // unsigned
number = [coder decodeObjectForKey:key];
unsignedValue = [number unsignedIntValue];
[self setValue:@(unsignedValue) forKey:key];
break;
case 's': // short
number = [coder decodeObjectForKey:key];
shortValue = [number shortValue];
[self setValue:@(shortValue) forKey:key];
break;
default:
break;
}
}
}
@end
2.DataHandle文件
.h文件
.m文件
#import <sqlite3.h>
#import "DatabaseHandle.h"
#import "Model.h"
#define ARCHIVERKEY @"archiver"
static DatabaseHandle *dataHandle =nil;
@implementation DatabaseHandle
+ (DatabaseHandle*)shardInstnce{
@synchronized(self){
if (dataHandle == nil) {
dataHandle = [[DatabaseHandle alloc]init];
}
return dataHandle;
}
}
//打开数据库
static sqlite3 *db = nil;
- (void)openDB{
if (db !=nil) {
return;
}
NSString *filePath = [self useCachesPathSqlite:@"WatchBall.sqlite"];
NSLog(@"db filePath = %@",filePath);
int result = sqlite3_open(filePath.UTF8String, &db);
if (result ==SQLITE_OK) {
NSString *createModelSql = @"CREATE TABLE ModelList(ID TEXT PRIMARY KEY,title TEXT,imageUrl TEXT,data BLOB)";
//执行参数?
sqlite3_exec(db, [createModelSql UTF8String], NULL, NULL, NULL);
}
}
- (void)closeDB{
int result = sqlite3_close(db);
if (result ==SQLITE_OK) {
db = nil;
NSLog(@"关闭成功");
}
}
//插入收藏活动
- (void)insertNewactivity:(Model *)model{
[self openDB];
static sqlite3_stmt *stmt = nil;
NSString *sql = @"insert into ModelList(ID,title,imageUrl,data) values (?,?,?,?)";
int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);
if (result ==SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [model.ID UTF8String], -1, nil);
sqlite3_bind_text(stmt, 2, [model.title UTF8String], -1, nil);
sqlite3_bind_text(stmt, 3, [model.imageUrl UTF8String], -1, nil);
NSString *archiverKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,model.ID];
NSData *data = [self dataOfArchiverObject:model forKey:archiverKey];
sqlite3_bind_blob(stmt, 4, [data bytes], (int)[data length], nil);
sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
}
- (void)deleteModelByID:(NSString *)ID{
[self openDB];
NSString *deleteSQL = [NSString stringWithFormat:@"delete from ModelList where ID ='%@'",ID];
char * error =nil;
int result = sqlite3_exec(db, deleteSQL.UTF8String, NULL, NULL, &error);
if (result == SQLITE_OK) {
NSLog(@"删除成功");
}else{
NSLog(@"删除失败 error = %s",error);
}
}
- (Model*)selectModelWithID:(NSString *)ID{
[self openDB];
sqlite3_stmt *stmt = nil;
NSString *sql = @"select data from ModelList where ID = ?";
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
Model *model = nil;
if (result ==SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [ID UTF8String], -1, NULL);
if (sqlite3_step(stmt) ==SQLITE_ROW) {
NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];
NSString *archiver = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID];
model = [self unarchiverObject:data forKey:archiver];
}
}
sqlite3_finalize(stmt);
return model;
}
- (NSArray*)selectAllModel{
[self openDB];
sqlite3_stmt *stmt = nil;
NSString *sql = @"select ID,data from ModelList";
int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
NSMutableArray *activityArray = [NSMutableArray array];
if (result == SQLITE_OK) {
while (sqlite3_step(stmt) ==SQLITE_ROW) {
NSString *ID = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 0)];
NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)];
NSString *modelKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID];
Model * model = [self unarchiverObject:data forKey:modelKey];
[activityArray addObject:model];
NSLog(@"%@",model);
}
}
sqlite3_finalize(stmt);
if (activityArray.count ==0) {
return nil;
}
return activityArray;
}
- (BOOL)isFavoriteModelWithID:(NSString *)ID{
Model *model = [self selectModelWithID:ID];
if (model ==nil) {
NSLog(@"没有收藏该条目");
return NO;
}
NSLog(@"已经收藏");
return YES;
}
#pragma ---文件路径处理----
////文件夹路径处理
- (NSString*)useCachesPathSqlite:(NSString*)databaseName{
NSString *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
NSString *filePath = [caches stringByAppendingPathComponent:databaseName];
return filePath;
}
#pragma ---归档处理---
- (NSData *)dataOfArchiverObject:(id)object forKey:(NSString*)key{
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
[archiver encodeObject:object forKey:key];
[archiver finishEncoding];
return data;
}
- (id)unarchiverObject:(NSData*)data forKey:(NSString *)key{
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
id object = [unarchiver decodeObjectForKey:key];
[unarchiver finishDecoding];
return object;
}
@end
3.基类Model
.h文件
.m文件
iOS中 学会如何对sqlite3 进行封装 (纯手工)的更多相关文章
- iOS中 学会如何对sqlite3 进行封装
#waring ---(看官注意) ---使用说明: ①在创建自定义model类之前让该类继承自文件中的Model类, ②为model类选一个NSString属性作为主键:(既,在初始化方法里面将从父 ...
- ios中 radioButton和DataPIcker,九宫格封装好使用
下载地址 http://pan.baidu.com/share/link?shareid=2894506499&uk=923776187 引用这几个文件 radiobutton.封装好单选按钮 ...
- ios中xml和html解析(封装)
下载地址 http://pan.baidu.com/share/link?shareid=2902188921&uk=923776187 GDataXML和TFHpple配置是一样的(配置方 ...
- QF——iOS中的数据库操作:SQLite数据库,第三方封装库FMDB,CoreData
SQLite数据库: SQLite是轻量级的数据库,适合应用在移动设备和小型设备上,它的优点是轻量,可移植性强.但它的缺点是它的API是用C写的,不是面向对象的.整体来说,操作起来比较麻烦.所以,一般 ...
- 转载 -- iOS中SDK的简单封装与使用
一.功能总述 在博客开始的第一部分,我们先来看一下我们最终要实现的效果.下图中所表述的就是我们今天博客中要做的事情,下方的App One和App Two都植入了我们将要封装的LoginSDK, 两个A ...
- 数据库sqlite3的使用-ios中引用方法
一.简单说明 在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件. 导入头文件,可以使用库中的函数(是纯C语言的) 二.具体说明 新建一个项目,在项目的主界面 ...
- iOS中数据库应用基础
iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...
- iOS中的数据持久化方式
iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data. 1.属性列表 涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults ...
- iOS中常用的四种数据持久化技术
iOS中的数据持久化方式,基本上有以下四种:属性列表 对象归档 SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults st ...
随机推荐
- CentOS6.5安装MySQL5.6
CentOS6.5安装MySQL5.6,开放防火墙3306端口,允许其他主机使用root账户密码访问MySQL数据库 查看操作系统相关信息 ** 该查看方法只适用于CentOS6.5 (lsb_rel ...
- python中对象、类型和元类之间的关系
在python中对象.类型和元类构成了一个微妙的世界. 他们有在这个世界里和平共处,相辅相成.它们遵循着几条亘古不变的定律: 1.python中无处不对象 2.所有对象都有三种特性:id.类型.值 3 ...
- MySQL的存储引擎与日志说明
1.1 存储引擎的介绍 1.1.1 文件系统存储 文件系统:操作系统组织和存取数据的一种机制.文件系统是一种软件. 类型:ext2 3 4 ,xfs 数据. 不管使用什么文件系统,数据内容不会变化, ...
- 《编程语言实现模式》【PDF】下载
<编程语言实现模式> 编程语言实现模式旨在传授构建语言应用(工具)的经验和理念,教读者构建自己的语言应用.这里的语言应用并非特指用编译器或解释器实现编程语言,而是泛指任何处理.分析.翻译输 ...
- 教程:安装禅道zentao项目管理软件github上的开发版
该文章转自:吕滔博客 直接从github拉下来的禅道的源码,是跑不起来的.除非你按我的教程来做...哈哈哈(不要脸)~~~~ 禅道官网提供的版本包是带了有安装文件,并有打包合成一些css.js文件的. ...
- ASP.NET Cookie 概述
什么是 Cookie? Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递.Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息. 例如,如果在用 ...
- 使用Libmicrohttpd搭建内嵌(本地)服务器
Libmicrohttpd简介 GNU Libmicrohttpd是一个用来在项目中内嵌http服务器的C语言库,它具有以下几个非常鲜明的特点: C语言库,小而快. API非常简单,且都是可重入的. ...
- Docker容器中开始.NETCore之路
一.引言 开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境 ...
- 如何减轻ajax定时触发对服务器造成的压力和带宽的压力?ajax-长轮训
AJAX长轮询的方法来解决频繁对后台的请求,进一步减小压力 在实现过程发现AJAX的多次请求会出现多线程并发的问题又使用线程同步来解决该问题 个人对ajax长轮询的一点愚见 ajax请示后台时,后台程 ...
- FPGA浮点数定点化
因为在普通的fpga芯片里面,寄存器只可以表示无符号型,不可以表示小数,所以在计算比较精确的数值时,就需要做一些处理,不过在altera在Arria 10 中增加了硬核浮点DSP模块,这样更加适合硬件 ...