文档章节

简单封装sqlite3 实现实体对象与关系型数据库的相关操作【IOS】

JasonMs
 JasonMs
发布于 2015/10/15 21:19
字数 1015
阅读 803
收藏 5
点赞 0
评论 0

源码如下,只有一个类文件

//
//  DBHelper.h
//
//  Created by Jason_Msbaby on 15/10/15.
//  Copyright © 2015年 张杰. All rights reserved.
//
/**
 *  简单封装了对于sqlite的使用 没有加入对事务及其他复杂的特性
    基于传入sql语句的方式进行执行
    使用单例模式
    根据model对象自动创建表 只支持 NSInter NSString float 数据类型的支持
    默认增加 id自增主键
    默认采用单数据库模式 默认数据库名字为databse.sqlite
 */
#import <Foundation/Foundation.h>

@interface DBHelper : NSObject

/**
 *  创建单例对象
 *
 *  @return 返回本类实例
 */
+(instancetype)defaultManger;
/**
 *  创建数据表
 *
 *  @param sql sql语句
 *
 *  @return 返回 创建是否成功的标识
 */
-(BOOL)creatTabel:(NSString*)sql;
/**
 *  使用实体类型进行自动建表
 *
 *  @param tableName 表名称
 *  @param modelType 实体类型 用于自动检索实体的属性
 *
 *  @return 返回bool
 */
-(BOOL)createTabel:(NSString*)tableName modelType:(Class)modelType;
/**
 *  增删改语句通用执行方法
 *
 *  @param sql 传入sql语句
 *
 *  @return 返回bool值
 */
-(BOOL)execute:(NSString*)sql;

/**
 *  执行查询
 *
 *  @param sql 传入sql语句
 *
 *  @return 返回 数组<字典> 字典的键与数据库字段名相同
 */
-(NSMutableArray*)executeQuery:(NSString*)sql;

/**
 *  插入一个实体对象到某一张表
 *
 *  @param model     实体对象
 *  @param tableName 表名
 *
 *  @return 返回bool值
 */
-(BOOL)insertModel:(id)model TableName:(NSString *)tableName;

@end
//
//  DBHelper.m
//  douBan
//
//  Created by Jason_Msbaby on 15/10/15.
//  Copyright © 2015年 张杰. All rights reserved.
//
#import <objc/runtime.h>
#import "DBHelper.h"
#import <sqlite3.h>
#define CachePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]
#define DataBaseName @"database.sqlite"

@implementation DBHelper


static DBHelper *dbhelper;
static sqlite3 *sql3;
//********************************************* 具体实现部分 ***************************************//
+(instancetype)defaultManger{
    if (dbhelper == nil) {
        dbhelper = [DBHelper new];
    }
    return dbhelper;
}

-(BOOL)creatTabel:(NSString *)sql{
    return [self execute:sql];
}

-(BOOL)createTabel:(NSString *)tableName modelType:(Class)modelType{
    NSMutableString *sql = [NSMutableString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('id' INTEGER PRIMARY KEY AUTOINCREMENT,",tableName];
    NSArray *names =[NSArray arrayWithArray:[self allPropertyNameInClass:modelType]];
    for (NSDictionary *dic in names) {
        NSString *name = dic[@"name"];
        NSString *type = dic[@"type"];
        [sql appendString:[NSString stringWithFormat:@"'%@' %@ ,",name,type]];
    }
    NSString *realSql = [sql substringToIndex:sql.length-1];
    realSql = [realSql stringByAppendingString:@");"];
    NSLog(@"%@",realSql);
    
    return [self execute:realSql];
}
-(BOOL)execute:(NSString *)sql{
    [self open];
    int res = sqlite3_exec(sql3, sql.UTF8String, NULL, NULL, NULL);
    [self close];
    return !res;
}

-(NSMutableArray *)executeQuery:(NSString *)sql{
    [self open];
    sqlite3_stmt *stmt = nil;
    NSMutableArray *arr = [NSMutableArray array];
    int res = sqlite3_prepare(sql3, sql.UTF8String, -1, &stmt, NULL);
    if (res == SQLITE_OK) {
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int count = sqlite3_column_count(stmt);
            NSMutableDictionary *dic = [NSMutableDictionary dictionary];
            for (int i = 0; i < count; i++) {
                const char *columName = sqlite3_column_name(stmt, i);
                const char *value = (const char*)sqlite3_column_text(stmt, i);
                if (value!=NULL) {
                    NSString *columValue =[NSString stringWithUTF8String:value];
                    [dic setObject:columValue forKey:[NSString stringWithUTF8String:columName]];
                }else{
                    [dic setObject:@"" forKey:[NSString stringWithUTF8String:columName]];
                }
            }
            [arr addObject:dic];
        }
        sqlite3_finalize(stmt);
        [self close];
        return arr;
        
    }else{
        return nil;
    }
    return nil;
}
-(BOOL)insertModel:(id)model TableName:(NSString *)tableName{
    NSDictionary *dic = [self DictionaryFromModel:model];
    NSMutableString *keys = [NSMutableString string];
    NSMutableString *values = [NSMutableString string];
    for (int i = 0; i < dic.count; i++) {
        NSString *key = dic.allKeys[i];
        NSString *value = dic.allValues[i];
        [keys appendFormat:@"%@,",key];
        [values appendFormat:@"'%@',",value];
    }
    NSString *sql = [NSString stringWithFormat:@"insert into %@(%@) values(%@)",tableName,[keys substringToIndex:keys.length -1],[values substringToIndex:values.length - 1]];
    NSLog(@"%@",sql);
    return ![self execute:sql];
}

//********************************************* 本类辅助函数 ***************************************//

-(BOOL)open{
    NSString *fileName = [CachePath stringByAppendingPathComponent:DataBaseName];
    NSLog(@"path=%@",fileName);
    return !sqlite3_open(fileName.UTF8String, &sql3);
}
-(BOOL)close{
    return !sqlite3_close(sql3);
}
//字典与对象的转换函数
//对象转换为字典
-(NSDictionary*)DictionaryFromModel:(id)model{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    Class modelClass = object_getClass(model);
    unsigned int count = 0;
    objc_property_t *pros = class_copyPropertyList(modelClass, &count);
    
    for (int i = 0; i < count; i++) {
        objc_property_t pro = pros[i];
        NSString *name = [NSString stringWithFormat:@"%s", property_getName(pro)] ;
        id value = [model valueForKey:name];
        if (value !=nil) {
            [dic setObject:value forKey:name];
        }
    }
    free(pros);
    return dic;
}
//********************************************* 属性动态解析部分 ***************************************//
//Runtime辅助函数解析类的属性特征等行为
//获取属性的特征值
-(NSString*)attrValueWithName:(NSString*)name InProperty:(objc_property_t)pro{
    unsigned int count = 0;
    objc_property_attribute_t *attrs = property_copyAttributeList(pro, &count);
    for (int i = 0; i < count; i++) {
        objc_property_attribute_t attr = attrs[i];
        if (strcmp(attr.name, name.UTF8String) == 0) {
            return [NSString stringWithUTF8String:attr.value];
        }
    }
    free(attrs);
    return nil;
}

//获取属性的值
-(id)valueOfproperty:(objc_property_t)pro cls:(Class)cls{
    Ivar ivar = class_getInstanceVariable(cls, [self attrValueWithName:@"V" InProperty:pro].UTF8String);
    return object_getIvar(cls, ivar);
}

//获取类的所有属性名称与类型
-(NSArray *)allPropertyNameInClass:(Class)cls{
    NSMutableArray *arr = [NSMutableArray array];
    unsigned int count;
    objc_property_t *pros = class_copyPropertyList(cls, &count);
    for (int i = 0; i < count; i++) {
        NSString *name =[NSString stringWithFormat:@"%s",property_getName(pros[i])];
        NSString *type = [self attrValueWithName:@"T"  InProperty:pros[i]];
        //类型转换
        if ([type isEqualToString:@"q"]||[type isEqualToString:@"i"]) {
            type = @"INTEGER";
        }else if([type isEqualToString:@"f"] || [type isEqualToString:@"d"]){
            type = @"REAL";
        }else{
            type = @"TEXT";
        }
        NSDictionary *dic = @{@"name":name,@"type":type};
        [arr addObject:dic];
    }
    free(pros);
    return arr;
}

@end

© 著作权归作者所有

共有 人打赏支持
JasonMs

JasonMs

粉丝 7
博文 49
码字总数 20564
作品 1
朝阳
程序员
iOS开发系列--数据存取

概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库。例如前面IOS开发系列—Objective-C之Foundation框架的文章中提到归档、plist文件存储,包括偏好设...

jianxin160
2015/08/18
0
0
iOS数据存取(2)

SQLite3 SQLite3简介 SQLite3是一款开源的嵌入式关系型数据库,可移植性好、易使用、内存开销小。 SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中。比如下列的创表...

天机
2016/04/29
23
0
Entity Framework快速入门

实体框架(Entity Framework)简介 实体框架Entity Framework 是 ADO.NET 中的一组支持开发面向数据的软件应用程序的技术。是微软的一个ORM框架。 ORM知识补充:什么是O/R Mapping? 广义上,...

aicoder
2011/02/20
0
0
关于数据建模工具相关概念和思想

我们都知道,面向对象的分析和设计推荐我们从需求中提取出几类对象,即:实体域对象、逻辑域对象、事件域对象、UI对象。这些对象也就是所谓的领域模型(UI对象是否算领域模型的?哥拿不准),...

穿越星辰
2011/07/19
0
0
Hibernate框架(一)——总体介绍

作为SSH三大框架之一的Hibernate,是用来把程序的Dao层和数据库打交道用的,它封装了JDBC的步骤,是我们对数据库的操作更加简单,更加快捷。利用Hibernate框架我们就可以不再编写重复的JDBC代...

凡尘里的一根葱
2015/11/10
0
0
Spring.NET企业架构实践之 Nhibernate + WCF + ASP.NET MVC + NVelocity 对PetShop4.0重构(三)——持久层

什么是持久层?先解释什么是持久,英文persistence,将内存中的数据固化,保持在物理储存设备中。然而在企业应用中,往往通过关系型数据库来完成这一过程。那么持久层的定义是:相对于三层架...

长平狐
2012/06/11
949
0
JPA规范实现--OpenJPA

OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作,让开发者把注意力...

匿名
2008/09/07
7.7K
1
Entity Framework 实体框架的形成之旅--数据传输模型DTO和实体模型Entity的分离与联合B

在使用Entity Framework 实体框架的时候,我们大多数时候操作的都是实体模型Entity,这个和数据库操作上下文结合,可以利用LINQ等各种方便手段,实现起来非常方便,一切看起来很美好。但是如...

walb呀
2017/12/04
0
0
手撸一个简易Android数据库框架

一、简述 众所周知,移动端(不管是Android还是iOS)使用的数据库是Sqlite,这种小型的数据库很适合移动端存储大量的数据,使用上也跟mysql基本无差,但官方提供的API在操作性方面真不咋的,...

CSDN_LQR
2017/11/27
0
0
手撸一个简易Android数据库框架

一、简述 众所周知,移动端(不管是Android还是iOS)使用的数据库是Sqlite,这种小型的数据库很适合移动端存储大量的数据,使用上也跟mysql基本无差,但官方提供的API在操作性方面真不咋的,...

CSDN_LQR
2017/11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周一乱弹 —— 如果是你喜欢的女同学找你借钱

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享Michael Learns To Rock的单曲《Fairy Tale》 《Fairy Tale》- Michael Learns To Rock 手机党少年们想听歌,请使劲儿戳(这...

小小编辑
21分钟前
7
3
NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0
Linux网络基础、Linux防火墙

Linux网络基础 ip addr 命令 :查看网口信息 ifconfig命令:查看网口信息,要比ip addr更明了一些 centos 7默认没安装ifconfig命令,可以使用yum install -y net-tools命令来安装。 ifconfig...

李超小牛子
今天
1
0
[机器学习]回归--Decision Tree Regression

CART决策树又称分类回归树,当数据集的因变量为连续性数值时,该树算法就是一个回归树,可以用叶节点观察的均值作为预测值;当数据集的因变量为离散型数值时,该树算法就是一个分类树,可以很...

wangxuwei
昨天
1
0
Redis做分布式无锁CAS的问题

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。 public interface OrderService { public String getOrderNo();} public class OrderRe...

算法之名
昨天
11
0
143. Reorder List - LeetCode

Question 143. Reorder List Solution 题目大意:给一个链表,将这个列表分成前后两部分,后半部分反转,再将这两分链表的节点交替连接成一个新的链表 思路 :先将链表分成前后两部分,将后部...

yysue
昨天
1
0
数据结构与算法1

第一个代码,描述一个被称为BankAccount的类,该类模拟了银行中的账户操作。程序建立了一个开户金额,显示金额,存款,取款并显示余额。 主要的知识点联系为类的含义,构造函数,公有和私有。...

沉迷于编程的小菜菜
昨天
1
0
从为什么别的队伍总比你的快说起

在机场候检排队的时候,大多数情况下,别的队伍都要比自己所在的队伍快,并常常懊悔当初怎么没去那个队。 其实,最快的队伍只能有一个,而排队之前并不知道那个队快。所以,如果有六个队伍你...

我是菜鸟我骄傲
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部