iOS sqllite封装,不用写SQL语句才是封装的目的.


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class SQTool;
@class Cloumn;

typedef enum : NSUInteger
{
    Typeinteger,
    Typetext,
    Typereal,
} Type;

typedef void(^CreatTable)(NSString *tableName,NSArray*arr);
typedef void(^CreatTableNew)(NSString *name,NSArray<Cloumn *>*arr);
typedef void(^InsertInto)(NSString *tableName,NSArray *key,NSArray *valus);



// delete from team where stu_id=3
typedef void(^Delete)(NSString *tableName,NSDictionary *dic);


// update team setstu_name='zl',stu_password='zl123',stu_login='zhangsan' where stu_id=4
typedef void(^Update)(NSString *tableName ,NSDictionary *dicUpdate,NSDictionary *whereData);

typedef SQTool *(^Select)(NSArray *arr);
typedef SQTool *(^From)(NSString *str);
typedef SQTool *(^Where)(id obj);
typedef SQTool *(^Log)(void);

@interface SQTool : NSObject

@property (nonatomic, strong) NSString  *sql;
@property (nonatomic, copy) CreatTable creatTable;
@property (nonatomic, copy) CreatTableNew creatTableNew;
@property (nonatomic, copy) Select select;
@property (nonatomic, copy) From from;
@property (nonatomic, copy) Where where;
@property (nonatomic, copy) Log log;

@property (nonatomic, copy) InsertInto insertInto;
@property (nonatomic, copy) Delete deleteSql;
@property (nonatomic, copy) Update updateSql;

/**
 单例初始化方法 可以init方法
 */
+(instancetype)shareInstance;

/**  打开数据并创建表  */
-(BOOL)openDB;

/**
 关闭数据路
 */
-(void)closeDB;

/**
 增
 */
- (void)insertData:(NSArray *)sqlarr;

/**
 删
 */
-(void)deleteSql:(NSString *)sqlstr;

/**
 改
 @param sqlstr sql语句
 @return <#return value description#>
 */
-(BOOL)updateSql:(NSString *)sqlstr;

/**
 查
 @param SQL  SQL查询语句
 @return 返回查询结果 包装成数组
 */
-(NSArray *)querySQL:(NSString *)SQL;

/**
 数据库添加字段 字段存在会添加失败(没有判断表中是否存在此字段 用的不多所以没做)
 @param tableName <#tableName description#>
 @param cloumn <#cloumn description#>
 */
-(void)alterColum:(NSString *)tableName cloumn:(Cloumn *)cloumn;



@end


@interface Cloumn : NSObject

/**
 字段名
 */
@property (nonatomic, strong) NSString *name;

/**
 数据存储类型
 */
@property (nonatomic, assign) Type type;


/**
 跟新数据库添加字段默认值
 */
@property (nonatomic, strong) NSString *value;

/**
 非空自增
 */
@property (nonatomic, assign) BOOL isAUTOINCREMENT;


/**
 初始化方法
 @param name 列的标题 名字 性别 年龄
 @param type 类型 整型 字符型等
 @return 返回sql单个字段模型
 */
-(instancetype)initWitNmae:(NSString *)name type:(Type)type;

@end

NS_ASSUME_NONNULL_END
#import "SQTool.h"
#import <sqlite3.h>

#define selectDefine @"select"
#define whereDefine  @"where"
#define fromDefine   @"from"

#define deleteDefine   @"delete"

#define deleteDefine   @"delete"



#define  _NOT_NULL_PRIMARY_KEY_AUTOINCREMENT @" NOT NULL PRIMARY KEY AUTOINCREMENT"
#define create_table_if_not_exists @"create table if not exists"
#define INSERT_INTO @"INSERT INTO"
#define VALUES @"VALUES"


#define SqlTableArrName @"SqlTableArrName"

/**
 * SQL语句常用操作
 增、删、改、查,CRUD,Create[新建], Retrieve[检索], Update[更新], Delete[删除]。
 
 * SQL语法写法特点
 1、不区分大小写(CREATE = create)
 2、每条语句以分号(;)结尾
 3、关键字建议大写
 
 * SQL语句常用关键字
 select、insert、update、delete、from、create、where、desc、order、by、group、table、alter、view、index等
 数据定义语句(DDL):包括create和drop等操作,在数据库中创建新表或删除表(create table或 drop table)
 数据操作语句(DML):包括insert、update、delete等操作,分别用于添加、修改、删除表中的数据
 数据查询语句(DQL):可以用于查询获得表中的数据,关键字select是DQL(也是所有SQL)用得最多的操作,其他DQL常用的关键字有where,order by,group by和having
 
 */

@interface SQTool ()

@property (nonatomic,assign) sqlite3 *db;

@end


@implementation SQTool

static SQTool *instance;
+(instancetype)shareInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

#pragma mark ————————— sql语句 —————————————

/**
 create table 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
 create table if not exists 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
 create table t_student (id integer, name text, age integer, score real) ;
 @return <#return value description#>
 */
-(CreatTable)creatTable
{
    return ^(NSString *name,NSArray *arr)
    {
        if (name) {
            
            self.sql = [NSString string];
            
            if (arr.count > 0)
            {
                self.sql = [NSString stringWithFormat:@"%@ %@ (%@)",create_table_if_not_exists, name,[arr componentsJoinedByString:@","]];
            }
            
            [self saveTableSqlWithName:name sql:self.sql];
        }
        
    };
}

#pragma mark ————————— 类型转换 —————————————
-(NSString *)stringFromType:(Type)type
{
    NSString *typeStr;
    switch (type) {
        case Typetext:
        {
            typeStr = @"text";
        }
            break;
        case Typeinteger:
        {
            typeStr = @"integer";
        }
            break;
        case Typereal:
        {
            typeStr = @"real";
        }
            break;
            
        default:
            break;
    }
    return typeStr;
}


/**
 create table 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
 create table if not exists 表名 (字段名1 字段类型1, 字段名2 字段类型2, …) ;
 create table t_student (id integer, name text, age integer, score real) ;
 @return <#return value description#>
 */
-(CreatTableNew)creatTableNew
{
    return ^(NSString *name,NSArray *arr)
    {
        if (name)
        {
            self.sql = [NSString string];
            
            if (arr.count > 0)
            {
                NSString *all=[NSString string];
                for (Cloumn *cl in arr)
                {
                    NSString * str = [NSString stringWithFormat:@"%@ %@",cl.name,[self stringFromType:cl.type]];
                    
                    if (cl.isAUTOINCREMENT == YES)
                    {
                        str = [str stringByAppendingString:_NOT_NULL_PRIMARY_KEY_AUTOINCREMENT];
                    }
                    
                    if (all.length > 0)
                    {
                        all = [all stringByAppendingString:@","];
                    }
                    
                    all = [all stringByAppendingString:str];
                }
                self.sql = [NSString stringWithFormat:@"%@ %@ (%@)",create_table_if_not_exists,name,all];
            }
            
        }
        [self saveTableSqlWithName:name sql:self.sql];
        
        [self openDB];
        [self closeDB];
    };
}

#pragma mark ————————— 保存建表语句 —————————————
-(void)saveTableSqlWithName:(NSString *)name sql:(NSString *)sql
{
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *arrName = [NSMutableDictionary dictionary];
    if ([user objectForKey:SqlTableArrName])
    {
        NSDictionary *dic  = [user objectForKey:SqlTableArrName];
        arrName = dic.mutableCopy;
    }
    
    if (sql)
    {
        [arrName setObject:sql forKey:name];
    }
    [user setObject:arrName forKey:SqlTableArrName];
    [user synchronize];
}

-(Select)select
{
    return ^(NSArray *name)
    {
        if (name.count > 0)
        {
            self.sql = [NSString stringWithFormat:@"%@ %@", selectDefine,[name componentsJoinedByString:@","]];
        }
        else
        {
            self.sql = [NSString stringWithFormat:@"%@ *",selectDefine];
        }
        return self;
    };
}

-(From)from
{
    return ^(NSString * str)
    {
        NSString *fromStr = [NSString stringWithFormat:@" %@ %@", fromDefine,str];
        self.sql = [self.sql stringByAppendingString:fromStr];
        return self;
    };
}

-(Where)where
{
    return ^(id obj)
    {
        NSString *str = [NSString string];
        if ([obj isKindOfClass:[NSDictionary class]])
        {
            NSDictionary *dic = obj;
            NSArray *arr = [dic allKeys];
            for (int i = 0; i <arr.count ; i++)
            {
                NSString *key = arr[i];
                NSString *value = [dic valueForKey:key];
                NSString *last  = [NSString stringWithFormat:@"%@ = '%@'",key,value];
                if (str.length > 0)
                {
                    last = [@" and " stringByAppendingString:last];
                }
                str = [str stringByAppendingString:last];
            }
            
        }
        else
        {
           str = [NSString stringWithFormat:@"%@",obj];
        }

        NSString *whereStr = [NSString stringWithFormat:@" %@ %@", whereDefine,str];
        self.sql = [self.sql stringByAppendingString:whereStr];
        return self;
    };
}

-(Log)log
{
    return ^()
    {
        NSLog(@"%@",self.sql);
        return self;
    };
}

#pragma mark ————————— 插入语句 —————————————
- (InsertInto)insertInto
{
    return ^(NSString *name, NSArray *key ,NSArray *values)
    {
        NSString *strm  =[NSString string];
        
        for (NSString * str  in values)
        {
            NSString *s = [NSString stringWithFormat:@"'%@'",str];
            if (strm.length > 0)
            {
                s = [@"," stringByAppendingString:s];
            }
            strm = [strm stringByAppendingString:s];
        }
        self.sql = [NSString stringWithFormat:@"%@ %@ (%@) %@ (%@);",INSERT_INTO,name,[key componentsJoinedByString:@","],VALUES,strm];
    };
}

#pragma mark ————————— 增 —————————————
- (void)insertData:(NSArray *)sqlarr
{
    [self openDB];
    //1.创建插入数据的sql语句(多条)
    NSMutableString * mstr = [NSMutableString string];
    for (NSString *str  in sqlarr)
    {
        [mstr appendString:str];
    }
    //2.执行sql语句
    int ret = sqlite3_exec(_db, mstr.UTF8String, NULL, NULL, NULL);
    //3.判断执行结果
    if (ret == SQLITE_OK)
    {
        NSLog(@"插入成功");
    }
    else
    {
        NSLog(@"插入失败");
    }
    [self closeDB];
}



#pragma mark ————————— 删除语句 —————————————
-(Delete)deleteSql
{
    return ^(NSString *name, NSDictionary *dic)
    {
        NSString *strm  = [NSString string];
        NSArray *arr = [dic allKeys];
        for (int i = 0; i< arr.count; i++)
        {
            NSString *key = arr[i];
            NSString *valeu = [dic objectForKey:key];
            NSString *s = [NSString stringWithFormat:@"%@ = '%@'",key,valeu];
            if (strm.length > 0)
            {
                s = [@" and " stringByAppendingString:s];
            }
            strm = [strm stringByAppendingString:s];
        }
        // @"delete from mqttlist where uid = '%@' and indexCount = '0'"
      self.sql =  [NSString stringWithFormat:@"delete from %@ where %@",name,strm];
    };
}

#pragma mark ————————— 删 —————————————
-(void)deleteSql:(NSString *)sqlstr
{
    [self openDB];
    // sql语句(多条)
    //    NSMutableString * mstr = [NSMutableString string];
    //    for (NSString *str  in sqlarr)
    //    {
    //        [mstr appendString:str];
    //    }
    sqlite3_stmt *stmt;
    int rst = sqlite3_prepare_v2(_db, sqlstr.UTF8String, -1, &stmt, NULL);
    
    // 判断是否删除成功
    if (rst==SQLITE_OK)
    {
        if (SQLITE_DONE == sqlite3_step(stmt))
        {
            NSLog(@" delete ok");
        }else
        {
            NSLog(@"delete fail");
        }
    }
    else
    {
       NSLog(@"delete fail");
    }
    [self closeDB];
}

#pragma mark ————————— 改语句 —————————————
-(Update)updateSql
{
    return ^(NSString *tableName ,NSDictionary *updateDic,NSDictionary *whereDic)
    {
        NSString *strm  = [NSString string];
        NSArray *arr = [whereDic allKeys];
        for (int i = 0; i< arr.count; i++)
        {
            NSString *key = arr[i];
            NSString *valeu = [whereDic objectForKey:key];
            
            NSString *s = [NSString stringWithFormat:@"%@ = '%@'",key,valeu];
            if (strm.length > 0)
            {
                s = [@" and " stringByAppendingString:s];
            }
            strm = [strm stringByAppendingString:s];
        }
        
        NSString *upstr = [NSString string];
        NSArray *upArr = [updateDic allKeys];
        
        
        for (int i = 0; i< upArr.count; i++)
        {
            NSString *key = upArr[i];
            NSString *valeu = [updateDic objectForKey:key];
            
            NSString *s = [NSString stringWithFormat:@"%@ = '%@'",key,valeu];
            if (upstr.length > 0)
            {
                s = [@"," stringByAppendingString:s];
            }
            upstr = [upstr stringByAppendingString:s];
        }
        // update team set stu_name='zl',stu_password='zl123',stu_login='zhangsan' where stu_id=4
        self.sql =  [NSString stringWithFormat:@"update %@ set %@ where %@",tableName,upstr,strm];
        
    };
}

#pragma mark ————————— 改 —————————————
// "update team setstu_name='zl',stu_password='zl123',stu_login='zhangsan' where stu_id=4"
-(BOOL)updateSql:(NSString *)sqlstr
{
    [self openDB];
    // sql语句(多条)
    //    NSMutableString * mstr = [NSMutableString string];
    //    for (NSString *str  in sqlarr)
    //    {
    //        [mstr appendString:str];
    //    }
    sqlite3_stmt *stmt;
    int rst = sqlite3_prepare_v2(_db, sqlstr.UTF8String, -1, &stmt, nil);
    // 判断是否修改成功
    if (rst == SQLITE_OK)
    {
        if (SQLITE_DONE == sqlite3_step(stmt))
        {
            NSLog(@"update ok");
            return YES;
        }
        else
        {
            NSLog(@"update fail = %d",rst);
            return NO;
        }
    }
    else
    {
        NSLog(@"update fail = %d",rst);
        return NO;
    }
}


#pragma mark ————————— 查 —————————————
-(NSArray *)querySQL:(NSString *)SQL
{
    [self openDB];
    
    //准备查询
    // 1> 参数一:数据库对象
    // 2> 参数二:查询语句
    // 3> 参数三:查询语句的长度:-1
    // 4> 参数四:句柄(游标对象)
    //    sqlite3_prepare_v2(<#sqlite3 *db#>, <#const char *zSql#>, <#int nByte#>, <#sqlite3_stmt **ppStmt#>, <#const char **pzTail#>)
    sqlite3_stmt *stmt = nil;
    if (sqlite3_prepare_v2(self.db, SQL.UTF8String, -1, &stmt, nil) != SQLITE_OK)
    {
        NSLog(@"准备查询失败!");
        return NULL;
    }
    //准备成功,开始查询数据
    //定义一个存放数据字典的可变数组
    NSMutableArray *dictArrM = [[NSMutableArray alloc] init];
    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        //一共获取表中所有列数(字段数)
        int columnCount = sqlite3_column_count(stmt);
        //定义存放字段数据的字典
        NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
        for (int i = 0; i < columnCount; i++)
        {
            // 取出i位置列的字段名,作为字典的键key
            const char *cKey = sqlite3_column_name(stmt, i);
            NSString *key = [NSString stringWithUTF8String:cKey];
            
            //取出i位置存储的值,作为字典的值value
            const char *cValue = (const char *)sqlite3_column_text(stmt, i);
            NSString *value;
            if (cValue)
            {
                value = [NSString stringWithUTF8String:cValue];
            }
            else
            {
                value = [NSString stringWithFormat:@"nil"];
            }
            
            //将此行数据 中此字段中key和value包装成 字典
            [dict setObject:value forKey:key];

        }
        
        [dictArrM addObject:dict];
        
    }
    return dictArrM;
}


-(void)alterColum:(NSString *)tableName cloumn:(Cloumn *)cloumn
{
    
    //在已经创建好的表格中插入add字段的SQ语句
    NSString *addStr = [NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN '%@' %@ default %@",tableName,cloumn.name,[self stringFromType:cloumn.type],cloumn.value];
    
    sqlite3_stmt *stmt;
    int rst = sqlite3_prepare_v2(_db, addStr.UTF8String, -1, &stmt, nil);
    // 判断是否修改成功
    if (rst == SQLITE_OK)
    {
        if (SQLITE_DONE == sqlite3_step(stmt))
        {
            NSLog(@"alter ok");
        }
        else
        {
            NSLog(@"alter fail = %d",rst);
        }
    }
    else
    {
        NSLog(@"alter fail = %d",rst);
    }
// 增加表字段ALTERTABLE表名ADDCOLUMN字段名字段类型删除表字段ALTERTABLE表名DROPCOLUMN字段名修改表字段ALTERTABLE表名RENAMECOLUMN旧字段名TO新字段名 
}

#pragma mark -
#pragma mark ————————— 数据库擦做 —————————————
-(BOOL)openDB
{
    //app内数据库文件存放路径-一般存放在沙盒中
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *DBPath = [documentPath stringByAppendingPathComponent:@"appDB.sqlite"];
    //创建(指定路径不存在数据库文件)/打开(已存在数据库文件) 数据库文件
    //sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)  filename:数据库路径  ppDb:数据库对象
    if (sqlite3_open(DBPath.UTF8String, &_db) != SQLITE_OK)
    {
        NSLog(@"数据库打开失败");
        return NO;
    }
    else
    {
        NSLog(@"打开成功创建表");
        return [self creatTablesl];
    }
}

#pragma mark ————————— 建表sql语句  —————————————
-(BOOL)creatTablesl
{
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    NSDictionary *dic = [user objectForKey:SqlTableArrName];
    NSArray * SQL_ARR = [dic allValues];
    return [self creatTableExecSQL:SQL_ARR];
}

#pragma mark ————————— 便利数组创建表 —————————————
-(BOOL)creatTableExecSQL:(NSArray *)SQL_ARR
{
    for (NSString *SQL in SQL_ARR)
    {
        if (![self execSQL:SQL])
        {
            return NO;
        }
    }
    return YES;
}

#pragma mark ————————— 执行建表 SQL 语句 —————————————
-(BOOL)execSQL:(NSString *)SQL
{
    char *error;
    if (sqlite3_exec(self.db, SQL.UTF8String, nil, nil, &error) == SQLITE_OK)
    {
        NSLog(@"创建表成功");
        return YES;
    }
    else
    {
        NSLog(@"SQL语句出错:%s",error);
        return NO;
    }
}

#pragma mark 关闭数据库
- (void)closeDB
{
    int result = sqlite3_close(_db);
    if (result == SQLITE_OK)
    {
        NSLog(@"数据库关闭成功");
        _db = nil;
    }
    else
    {
        NSLog(@"数据库关闭失败");
    }
}

@end


@implementation Cloumn

-(instancetype)initWitNmae:(NSString *)name type:(Type)type;
{
    self = [super init];
    if (self)
    {
        self.name = name;
        self.type = type;
        self.isAUTOINCREMENT = NO;
    }
    return self;
}

@end
// 调用
#import "ViewController.h"
#import "SQTool.h"

@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    SQTool *sq3 = [[SQTool alloc]init];
    
    // 表名
    NSString *tableName = @"Student";
    
    // 建表添加的字段模型如下
    Cloumn *cloumn  = [[Cloumn alloc]initWitNmae:@"id" type:(Typeinteger)];
    // id 为自增
    cloumn.isAUTOINCREMENT = YES;
    Cloumn *cloumn2  = [[Cloumn alloc]initWitNmae:@"name" type:(Typetext)];
    Cloumn *cloumn3  = [[Cloumn alloc]initWitNmae:@"time" type:(Typetext)];
    
    // 传入模型创建表
    sq3.creatTableNew(tableName, @[cloumn,cloumn2,cloumn3]);
    
    //-----------增---------------
    
    NSDictionary *dic = @{@"name":@"joHasns",@"time":[NSDate date]};
    // 插入数据t单条 每调用一侧创建一条 insertInto 创建的sql语句 存在 sq3.sql 里面
    sq3.insertInto(tableName, [dic allKeys], [dic allValues]);
    
    //  insertData  支持多条插入
    //    [sq3 insertData:@[sq3.sql]];
    
    //------------删--------------
    NSDictionary *dic2 = @{@"id":@"10", @"name":@"joHasns"};
    sq3.deleteSql(tableName, dic2);
    [sq3 deleteSql:sq3.sql];
    
    //--------------改------------
    NSDictionary *upDic = @{@"name":@"ABCD"};
    NSDictionary *whereDic = @{@"id":@"9"};
    sq3.updateSql(tableName, upDic, whereDic);
    [sq3 updateSql:sq3.sql];

    //------------更新数据库 添加字段--------------
    Cloumn *cloumn4  = [[Cloumn alloc]initWitNmae:@"age" type:(Typetext)];
    cloumn4.value = @"0";
//    [sq3 alterColum:tableName cloumn:cloumn4];
    
    //------------查--------------
    // 方式 - 每个条件对应一个字典的 key Value()
    NSDictionary *chaDic = @{@"id":@"1",@"name":@"joHasns"};
    
    // 带条件查找 参数可以是字典
//     sq3.select(@[]).from(tableName).where(chaDic);
    
    // 方式二 字符串
    sq3.select(@[]).from(tableName).where(@"id = '1'");
    
    // 不带条件查找语句
    //    sq3.select(@[]).from(tableName);
    
    // 查找
    NSArray *arr = [sq3 querySQL:sq3.sql];
    NSLog(@"%@",arr );
}
@end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值