LKDBHelper的各种接口使用方式,及各种sql组合条件语句。

1 篇文章 0 订阅



LKDBHelper 、FMDB的简介。

在项目的开发过程中,我们大部分时候都需要对数据做一个持久化的操作,最典型的就是 IM 类型的项目,消息都要做保存。 还有就是像个人重要的信息,一般也会存本地,和服务器做一个同步处理。 数据的持久化可以有多种方法。 这里简单讲讲 FMDB 、以及 基于FMDB 二次封装,提供简单接口的 LKDBHelper 第三方库的使用。

LKDBHelper Git 地址 : https://github.com/li6185377/LKDBHelper-SQLite-ORM


部分接口整合,代码。

只要是继承 NSObject  的类,都可以使用 LKDBHelper 的接口进行对 Model 的一个增删改查。 (可以创建一个 BaseModel 的基类,然后其他Model 都继承于此,这样方法统一管理 Model)

直接上代码 :

1.先创建一个简单的工程 ,再创建一个 LKModelTest 类。 (带上各种类型的属性)

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface LKModelTest : NSObject

@property (nonatomic, assign) int ID;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) BOOL isMan;

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, strong) NSData *data;
@property (nonatomic, assign) CGFloat floatValue;
@property (nonatomic, assign) CGRect frame;
@property (nonatomic, assign) CGPoint point;
@property (nonatomic, assign) NSRange *range;

@end

.m 文件这几个方法需要实现下。



#import "LKModelTest.h"

@implementation LKModelTest

//重载、初始化单例、使用的LKDBHelper
+ (LKDBHelper *)getUsingLKDBHelper {
    
    static LKDBHelper* db;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //DB 路径
        NSString* DBPath = [NSHomeDirectory() stringByAppendingPathComponent:@"DB/DBTest.db"];
        NSLog(@"%@", DBPath);
        db = [[LKDBHelper alloc] initWithDBPath:DBPath];
    });
    return db;
}

//在类 初始化的时候
+ (void)initialize {

    //如果getTableMapping 返回 nil, 会取全部属性, 如果有不想要的属性,可以使用
//    [self removePropertyWithColumnName:@"age"];
//    [self removePropertyWithColumnNameArray:@[@"age", @"name"]];
    
    //修改列名
//    [self setTableColumnName:@"MyAge" bindingPropertyName:@"age"];
    
    //手动设置关联外键变量名
//    [self setUserCalculateForCN:@""];
}

+ (void)dbDidAlterTable:(LKDBHelper *)helper tableName:(NSString *)tableName addColumns:(NSArray *)columns {

    LKErrorLog(@"your know %@",columns);
}

// 将要插入数据库
+ (BOOL)dbWillInsert:(NSObject *)entity {
    LKErrorLog(@"将要插入 : %@",NSStringFromClass(self));
    return YES;
}

//已经插入数据库
+ (void)dbDidInserted:(NSObject *)entity result:(BOOL)result {
    LKErrorLog(@"已经插入 : %@",NSStringFromClass(self));
}

+ (BOOL)dbWillUpdate:(NSObject*)entity {
    LKErrorLog(@"将要更新 : %@",NSStringFromClass(self));
    return YES;
}

+ (void)dbDidUpdated:(NSObject*)entity result:(BOOL)result {
    LKErrorLog(@"已经更新 : %@",NSStringFromClass(self));
}

+ (BOOL)dbWillDelete:(NSObject*)entity {
    LKErrorLog(@"将要删除 : %@",NSStringFromClass(self));
    return YES;
}

+ (void)dbDidDeleted:(NSObject*)entity result:(BOOL)result {
    LKErrorLog(@"已经删除 : %@",NSStringFromClass(self));
}

//手动or自动 绑定sql列
+ (NSDictionary *)getTableMapping {
    //返回nil 就是自动绑定所有列名
    return nil;
    
//    return @{@"age":@"Myage"};
}

//主键
+ (NSString *)getPrimaryKey {
    return @"ID";
}

///复合主键  这个优先级最高
//+(NSArray *)getPrimaryKeyUnionArray {
//    return @[@"name",@"age"];
//}

//表名
+ (NSString *)getTableName {
    return NSStringFromClass(self);
}

//是否将父实体类的属性也映射到sqlite库表
+ (BOOL)isContainParent {
    return YES;
}

@end




+ (NSDictionary *)getTableMapping;

这个方法是用来绑定当前表需要哪些列属性的, 如果返回 nil , 则默认绑定 Model 所有的属性名,作为 列名。  如果有个别不想绑定进数据库的,可以在 initialize 方法中,使用 [self removePropertyWithColumnName:@"列名"] ;    
来进行移除,也可以手动修改个别你需要更改列名的列:

[self setTableColumnName:@"新列名" bindingPropertyName:@"原列名"];

如果你有两张或者以上的表互相关联,需要设置外键的话,可以在 initialize 方法中调这个方法:

[self setUserCalculateForCN:@"关联的表,在当前属性中创建的变量名"];

这个参数什么意思? 比如: 有个A 类 和 B类 关联。

那么在 B 类的属性中,就会创建一个这样的属性

@property (nonatomic, strong) A *thisAObj;

则在 B 的这个方法里就要这么写:

[self setUserCalculateForCN:@"thisAObj"];



+ (NSString *)getTableName {
    return NSStringFromClass(self);
}


表也需要个表名, 所以这个方法 默认将 类名 作为 表名。

//主键
+ (NSString *)getPrimaryKey {
    return @"ID";
}

///复合主键  这个优先级最高
//+(NSArray *)getPrimaryKeyUnionArray {
//    return @[@"name",@"age"];
//}


一般情况下,你的Model数据也都会有一个唯一的值,这个值就可以来作为 主键, 主键的用途,后面再插入数据,或者删除,更改 都可以用来快速定位到某条数据条件,主键不能为空, 也不可能重复,如果你 保存某条 数据进去,但是主键对应的数据已经存在,则会覆盖那条数据。 复合主键,相当于多个条件一起约束一条数据,这种情况适用于当一个主键不能满足的时候。


//是否将父实体类的属性也映射到sqlite库表
+ (BOOL)isContainParent {
    return YES;
}

这个方法是设置 是否需要将父类的属性 也一起绑定在表中。


Model 的方法大致就这样设置 基本上就行了。


接下来在 ViewController.m 中,开始使用数据库存储。


///获取 LKTest 类使用的 LKDBHelper
    LKDBHelper *globalHelper = [LKModelTest getUsingLKDBHelper];
    [globalHelper dropAllTable];
    
    //清空表数据  clear table data
    [LKDBHelper clearTableData:[LKModelTest class]];
    
    LKModelTest *model = [LKModelTest new];
    model.name = @"张三1";
    model.nickName = @"马蓉婊子";
    model.isMan = YES;
    
    model.image = [UIImage imageNamed:@"imageValue"];
    model.color = [UIColor blueColor];
    model.date = [NSDate new];
    model.data = [@"yutianlong9306" dataUsingEncoding:NSUTF8StringEncoding];
    model.floatValue = 3.1415926f;
    model.frame = CGRectMake(0, 0, 100, 100);
    model.point = CGPointMake(200, 200);    
    
    //插入5条数据
    for (int i = 1; i < 6 ; i++) {
        model.ID = i;
        model.age = 20 + i;
        [model saveToDB];
    }

先插入 5 条 Model 数据。

下面的代码, 就是各种SQL 条件组合查询语句 : (最后会附上Demo 下载地址)

sleep(2);
    
    NSMutableArray *searchResultArray = nil;

    //同步搜索 执行sql语句 把结果再变成对象 **************查询操作*******
    
    // sql 1    查找表所有记录
    NSString *sql1 = @"select * from LKModelTest";
    searchResultArray = [globalHelper searchWithSQL:sql1 toClass:[LKModelTest class]]; 
    
    addText(@"********** 查找表所有记录 \n");
    
    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    
    // sql 2    按条件查询 (多条件)
    NSString *sql2 = @"select * from LKModelTest where name = '张三1' and age = 22";
    searchResultArray = [globalHelper search:[LKModelTest class] withSQL:sql2];
    
    
    addText(@"********** 按条件查询 (多条件) \n");
    
    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    
    // sql 3    条件使用动态参数 ? ,即接口传进来的,search使用如下接口
    NSString *sql3 = @"select * from LKModelTest where name = ?";
    NSString *name = @"张三1";     //假设这个 name 是接口传进来的 , 就可以有以下的写法
    searchResultArray = [globalHelper search:[LKModelTest class] withSQL:sql3, name];
    
    
    addText(@"********** 条件使用动态参数 ? \n");

    for (id obj in searchResultArray) {
        addText(@"%@", [obj printAllPropertys]);
    }
    //*********************查询操作************************************
    
    

    //使用对象对进查询操作  orderBy 可以指定某个列倒叙查询 offset是跳过多少行 count是查询多少条(为0查询所有)
    
    //  无条件查询 10 条
    searchResultArray = [LKModelTest searchWithWhere:nil orderBy:nil offset:0 count:10];
    
    //  无条件查询 某个列的值
    searchResultArray = [LKModelTest searchColumn:@"age" where:nil orderBy:nil offset:0 count:10];
    
    //  根据一个自增长的列,倒叙查询 最新10条数据  (自增长的列可以是 自定义属性ID,也可以是自带的 rowid)
    searchResultArray = [LKModelTest searchWithWhere:nil orderBy:@"ID desc" offset:0 count:10];
    
    //  根据 and 条件 查询所有数据
    NSString *conditions = @"age = 23 and name = '张三1'";
    searchResultArray = [LKModelTest searchWithWhere:conditions orderBy:nil offset:0 count:0];
    
    //  根据 字典条件,查询所有数据
    NSDictionary *conditions1 = @{@"age" : @23, @"name" : @"张三1"};
    searchResultArray = [LKModelTest searchWithWhere:conditions1 orderBy:nil offset:0 count:0];
    
    //  根据 or 条件,查询所有数据
    NSString *conditions2 = @"age = 23 or ID = 5";
    searchResultArray = [LKModelTest searchWithWhere:conditions2 orderBy:nil offset:0 count:0];
    
    //  根据 in 条件,查询所有数据
    NSString *conditions3 = @"age in (23, 24)";
    searchResultArray = [LKModelTest searchWithWhere:conditions3 orderBy:nil offset:0 count:0];
    
    //  根据 字典 in 条件,查询所有数据
    NSDictionary *conditions4 = @{@"age" : @[@23, @24]};
    searchResultArray = [LKModelTest searchWithWhere:conditions4 orderBy:nil offset:0 count:0];
    
    //  查询符合条件的数据有多少条
    NSString *conditions5 = @"age = 23 and name = '张三1'";
    NSInteger rowCount = [LKModelTest rowCountWithWhere:conditions5];
    NSLog(@"%ld", rowCount);
    
    
    for (id obj in searchResultArray) {
        [obj printAllPropertys];
    }


    //*********************更新操作*********************************

    //  带条件更新 , 一般来说,这种方式更新不需要where条件,因为会根据主键更新
    model.name = @"马蓉 婊子";
    BOOL isUpdate1 = [globalHelper updateToDB:model where:nil];
    
    //  更新 访问表名 更新内容跟条件进行更新
    BOOL isUpdate2 = [globalHelper updateToDBWithTableName:@"LKModelTest" set:@"name = '马蓉小婊砸'" where:@"age = 22"];
    
    //  根据 实类、条件进行更新
    BOOL isUpdate3 = [globalHelper updateToDB:[LKModelTest class] set:@"name = '马蓉小畜生'" where:@"age = 23"];

    
        
    //*********************删除操作*********************************

    //  根据model 删除 ,两种方式
    BOOL isDelete1 = [globalHelper deleteToDB:model];
    //or
    [model deleteToDB];
    

    //  根据条件,删除多条数据
    BOOL isDelete2 = [globalHelper deleteWithClass:[LKModelTest class] where:@"age >= 22 and age <= 24"];




Demo 会把部分 sql 执行接口打印在屏幕上,如果童鞋们 有需要打印其他信息,调用 addText(@""); 方法即可。




打印信息 :

                





Demo 下载地址:








































  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值