5.SQLite面相对象通用封装

5.SQLite面相对象通用封装,第1张

概述1.由来 在学习SQLite的时候,发现OC中提供的API是面向过程的方式,如果在开发中用到,那么每次都会重复的去走这个流程,打开数据库,执行sql,细节上的处理等。于是就在sqlite3的基础上,进行了通用封装,在以后的开发中直接使用即可,提高开发效率。 源代码托管:https://github.com/zhangint/OCSQLite/tree/master 2.注意 该封装只是针对通用的接 1.由来

在学习sqlite的时候,发现OC中提供的API是面向过程的方式,如果在开发中用到,那么每次都会重复的去走这个流程,打开数据库,执行sql,细节上的处理等。于是就在sqlite3的基础上,进行了通用封装,在以后的开发中直接使用即可,提高开发效率。
源代码托管:https://github.com/zhangint/OCSQLite/tree/master

2.注意

该封装只是针对通用的接口和使用方式,使用起来也比较简单,SQL语句,数据类型,数据值即可。
1.默认表的第一列为主键,创建表的时候需要注意。
2.如若有什么特殊功能或者细节控制,则该接口并不适用。
3.并不提供线程安全保证,需要用户自己进行控制。

3.运行效果接口说明

查询效果:

插入效果:

接口说明:
为了满足多行多列数据的插入和查询,采用了二位数组的方式,当某一列的数据值为空时,需填充[NSNull null];
直接贴头文件内容吧,描述的也很清晰
内部定义数据说明

//sqlite支持的5种数据类型typedef NS_ENUM(NSInteger,DataType){    DTNulL = 0,//NulL    DTINT,//整数    DTREAL,//浮点数    DTTEXT,//文本数据    DTBLOB          //二进制数据};

头文件接口

//@brIEf:打开数据库文件//@param:dbfile 数据库文件路径//@return: 0 成功 其它 失败的错误码- (NSInteger)openDB:(Nsstring *)dbfile;//@brIEf:关闭数据库连接//@return: YES 成功 NO 失败- (NSInteger)closeDB;//@breif: sql命令,返回执行状态//@return: 0 成功// 其它 错误码//@attention: 主要执行查询,状态获取等- (NSInteger)execsql:(Nsstring *)sql;//@brIEf: 执行SQL查询语句//@param: dataType 指定查询返回的数据类型(注意需为DataType的枚举值)//@return: 返回为双重数组,第一层为一行数据封装,第二层为列数据封装- (NSArray<NSArray *> *)sqlquery:(Nsstring *)sql                                    dataType:(NSArray<NSNumber *> *)dataType;//@brIEf: 数据插入//@param: sql 插入的SQL语句// data 绑定的值,而为数组形式,先封装一行数据,然后再封装// datatype 每一列数据的值//@return: >=0 影响的行数// -1 失败//@attention: 内部不检测值和类型是否匹配,需用户自己校验- (NSInteger)sqlInsert:(Nsstring*)sql data:(NSArray<NSArray *> *)data datatype:(NSArray *)datatype;//@brIEf: 根据错误码,返回错误描述信息- (Nsstring *)lastError:(NSInteger)errcode;
4.测试用例

1.多行数据插入

- (voID)insertClicked:(ID)sender{    //在插入数据的时候,先创建表    Nsstring *sql = @"create table if not exists test_table_1 \ (ID integer primary key autoincrement,\ name,\ passwd,\ address,\ age,\ photo,\ rank)";    NSLog(@"create table status:%ld",[_dbcon execsql:sql]);    //构造一行的数据    NSMutableArray *rowData_1 = [[NSMutableArray alloc] init];    [rowData_1 addobject:@"zhangint"];    [rowData_1 addobject:@"123456"];    [rowData_1 addobject:@"chengdu"];    [rowData_1 addobject:[NSNumber numberWithInt:25]];    Nsstring *pic1 = [[NSBundle mainBundle] pathForResource:@"zhangint" ofType:nil];    NSData *pic1_data = [NSData dataWithContentsOffile:pic1];    unsigned char* msg = (unsigned  char*)[pic1_data bytes];    [rowData_1 addobject:pic1_data];  //二进制    [rowData_1 addobject:[NSNumber numberWithfloat:2.3]];               //浮点数    NSMutableArray *rowData_2 = [[NSMutableArray alloc] init];    [rowData_2 addobject:@"love dog"];    [rowData_2 addobject:@"56789"];    [rowData_2 addobject:[NSNull null]];                                //string为空    [rowData_2 addobject:[NSNumber numberWithInt:33]];    Nsstring *pic2 = [[NSBundle mainBundle] pathForResource:@"xiaoyu" ofType:nil];    NSData *pic2_data = [NSData dataWithContentsOffile:pic2];    [rowData_2 addobject:pic2_data];    [rowData_2 addobject:[NSNumber numberWithfloat:3.3]];    NSMutableArray *rowData_3 = [[NSMutableArray alloc] init];    [rowData_3 addobject:@"xiaoxiaoxiao"];    [rowData_3 addobject:@"9990"];    [rowData_3 addobject:@"beijing"];    [rowData_3 addobject:[NSNumber numberWithInt:32]];    [rowData_3 addobject:[NSNull null]];                                //二进制位空    [rowData_3 addobject:[NSNumber numberWithfloat:5.4]];    //数据值的初始化    NSArray *tableArr = [[NSArray alloc] initWithObjects:rowData_1,rowData_2,rowData_3,nil];    //数据类型的初始化    NSArray *dataType = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:DTTEXT],[NSNumber numberWithInt:DTTEXT],[NSNumber numberWithInt:DTINT],[NSNumber numberWithInt:DTBLOB],[NSNumber numberWithInt:DTREAL],nil];    Nsstring *insertsql = @"insert into test_table_1 values(null,?,?)";    NSLog(@"insert res:%ld",[_dbcon sqlInsert:insertsql data:tableArr datatype:dataType]);

2.数据查询

- (voID) searchClicked:(ID)sender{    Nsstring *sql = @"select * from test_table_1";    NSArray *dataType = [[NSArray alloc] initWithObjects:[NSNumber numberWithBool:DTINT],nil];    NSArray<NSArray *> *searchRes;    searchRes = [_dbcon sqlquery:sql dataType:dataType];    NSInteger rows = [searchRes count];    NSLog(@"search rows:%ld",rows);    for (int i=0; i<rows; i++)    {        NSArray *rowData = searchRes[i];        NSNumber *IDnum = rowData[0];        Nsstring *name = rowData[1];        Nsstring *passed = rowData[2];        Nsstring *address = rowData[3];        NSNumber *age = rowData[4];        //NSData *img = rowData[5];        NSNumber *rank = rowData[6];        NSLog(@"ID:%d name:%@ passwd:%@ address:%@ age:%d photo not show rank:%.1f",IDnum.intValue,name,passed,address,age.intValue,rank.floatValue);    }    _searchRes = searchRes;
5.源代码

头文件:sqliteInter.h

//// sqliteInter.h// sqlitePro//// Created by zp on 15/12/26.// copyright © 2015年 ZP. All rights reserved.////@brIEf: sqlite通用接口封装//@attention: 1.本身并不提供线程安全,用户可以通过Serial dispatch Queue的方式,保证安全可靠访问// 2.只是对通用的使用方式进行了封装,很多细节或者特殊的使用方式并未覆盖#import <Foundation/Foundation.h>#import <sqlite3.h>//sqlite支持的5种数据类型typedef NS_ENUM(NSInteger,//文本数据    DTBLOB          //二进制数据};@interface sqliteInter : NSObject//错误码@property (assign,nonatomic) NSInteger lastErrCode;//@brIEf:打开数据库文件//@param:dbfile 数据库文件路径//@return: 0 成功 其它 失败的错误码- (NSInteger)openDB:(Nsstring *)dbfile;//@brIEf:关闭数据库连接//@return: YES 成功 NO 失败- (NSInteger)closeDB;//@breif: sql命令,返回执行状态//@return: 0 成功// 其它 错误码//@attention: 主要执行查询,状态获取等- (NSInteger)execsql:(Nsstring *)sql;//@brIEf: 执行SQL查询语句//@param: dataType 指定查询返回的数据类型(注意需为DataType的枚举值)//@return: 返回为双重数组,第一层为一行数据封装,第二层为列数据封装- (NSArray<NSArray *> *)sqlquery:(Nsstring *)sql                                    dataType:(NSArray<NSNumber *> *)dataType;//@brIEf: 数据插入//@param: sql 插入的SQL语句// data 绑定的值,而为数组形式,先封装一行数据,然后再封装// datatype 每一列数据的值//@return: >=0 影响的行数// -1 失败//@attention: 内部不检测值和类型是否匹配,需用户自己校验- (NSInteger)sqlInsert:(Nsstring*)sql data:(NSArray<NSArray *> *)data datatype:(NSArray *)datatype;//@brIEf: 根据错误码,返回错误描述信息- (Nsstring *)lastError:(NSInteger)errcode;@end

实现文件
sqliteInter.m

//// sqliteInter.m// sqlitePro//// Created by zp on 15/12/26.// copyright © 2015年 ZP. All rights reserved.///**@brIEf:sqlite数据接口封装,方便复用 * * */#import "sqliteInter.h"@interface sqliteInter ()//注意:sqlite3 为struct类型,不能用strong属性@property (assign,nonatomic) sqlite3 *database;@property (assign,nonatomic) sqlite3_stmt *stmt;@end@implementation sqliteInter- (NSInteger)openDB:(Nsstring *)dbfile{    //如果数据库已经打开,则先关闭    if (_database)    {        _lastErrCode = [self closeDB];        if (_lastErrCode != sqlITE_OK)        {            _lastErrCode = 0;            return 0;        }    }    _lastErrCode = sqlite3_open([dbfile UTF8String],&_database);    return _lastErrCode;}- (NSInteger)closeDB{    if (_database)    {        NSInteger num = 0;        //会关闭2次,2次失败,则失败        while (num < 2)        {            _lastErrCode = sqlite3_close(_database);            //关闭成功            if (sqlITE_OK == _lastErrCode)            {                _database = nil;                break;            }            sqlite3_finalize(_stmt);            num++;        }    }    return _lastErrCode;}- (NSInteger)execsql:(Nsstring *)sql{    //这个地方并不校验 _database == nil,errorcode 会有描述    _lastErrCode = sqlite3_exec(_database,[sql UTF8String],NulL,NulL);    //返回错误码    return _lastErrCode;}- (NSArray<NSArray *> *)sqlquery:(Nsstring *)sql                                    dataType:(NSArray<NSNumber *> *)dataType{    NSMutableArray *dataSet = [[NSMutableArray alloc] init];    NSInteger preRes = sqlite3_prepare_v2(_database,-1,&_stmt,nil);    if (preRes == sqlITE_OK)    {        while (sqlite3_step(_stmt) == sqlITE_ROW)        {            NSMutableArray *dataArr = [[NSMutableArray alloc] init];            int colNum = sqlite3_data_count(_stmt);            //获取列的数量            for (int i=0; i<colNum; i++)            {                [dataArr addobject:[self get_col_data:dataType[i].intValue statement:_stmt col:i]];            }            [dataSet addobject:dataArr];        }    }    sqlite3_finalize(_stmt);    return dataSet;}- (ID) get_col_data:(DataType)dbtype statement:(sqlite3_stmt *)stmt col:(NSInteger)col{    switch (dbtype) {        case DTNulL:            return [NSNull null];            break;        case DTINT:{            //(int)col 强制转化,避免警告            NSNumber *number = [NSNumber numberWithInt:sqlite3_column_int(stmt,(int)col)];            return number;            break;            }        case DTREAL:{            NSNumber *number = [NSNumber numberWithfloat:sqlite3_column_double(stmt,(int)col)];            return number;            }        case DTTEXT:{            Nsstring *cellData;            char* str = (char*)(char*)sqlite3_column_text(stmt,(int)col);            if (str != NulL)            {                cellData = [Nsstring stringWithFormat:@"%s",str];            }            else            {                //当为空的时候,为一个空对象                cellData = @"";            }            return cellData;        }        //二进制的处理        case DTBLOB:{            NSInteger len = sqlite3_column_bytes(stmt,(int)col);            NSData *cellData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt,(int)col) length:len];            return cellData;        }        default:            break;    }    return  [NSNull null];}- (NSInteger)sqlInsert:(Nsstring*)sql data:(NSArray<NSArray *> *)data datatype:(NSArray *)datatype{    NSInteger effectNum = 0;    int preStatus = sqlite3_prepare_v2(_database,NulL);    if (preStatus == sqlITE_OK)    {        for (int i=0; i<data.count; i++)        {            NSArray *rowData = data[i];            for (int col=0; col<rowData.count; coL++)            {                NSNumber *type = datatype[col];                switch (type.intValue) {                    case DTNulL:                        sqlite3_bind_null(_stmt,col+1);                        break;                    case DTINT:{                        NSNumber *number = rowData[col];                        sqlite3_bind_int(_stmt,col+1,number.intValue);                        break;                    }                    case DTREAL:{                        NSNumber *real = rowData[col];                        sqlite3_bind_double(_stmt,real.floatValue);                        break;                    }                    case DTTEXT:{                        Nsstring *str;                        if (rowData[col] == [NSNull null])                        {                            str = @"";                        }                        else                        {                            str = rowData[col];                        }                        sqlite3_bind_text(_stmt,[str UTF8String],NulL);                        break;                    }                    case DTBLOB:{                        NSData *msg;                        if (rowData[col] == [NSNull null])                        {                            msg = [[NSData alloc] initWithBytes:@"" length:1];                        }                        else                        {                            msg = rowData[col];                        }                        sqlite3_bind_blob(_stmt,[msg bytes],(int)[msg length],NulL);                        break;                    }                    default:                        break;                } /*switch */            } //for            if (sqlite3_step(_stmt) == sqlITE_DONE)            {                effectNum++;            }            //需要重置statement            sqlite3_reset(_stmt);        } /*for*/    } /*if*/    sqlite3_finalize(_stmt);    return effectNum;    //这种用法不对    //return sqlite3_changes(_database);}- (Nsstring *)lastError:(NSInteger)errcode{    return [Nsstring stringWithUTF8String:sqlite3_errstr((int)errcode)];}@end
总结

以上是内存溢出为你收集整理的5.SQLite面相对象通用封装全部内容,希望文章能够帮你解决5.SQLite面相对象通用封装所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1168531.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存