LKDBHelper的各种接口使用方式,及各种sql组合条件语句。
2016-08-19 10:48
1236 查看
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 下载地址:
http://download.csdn.net/detail/yutianlong9306/9607446
相关文章推荐
- yii框架中findall方法取数据使用总结,包括select各种条件,where条件,order by条件,limit限制以及使用单纯sql语句query时占位符的使用等
- ireport中当使用connection方式获得数据源时如何构造sql语句的where条件。
- mybatis学习之路----动态sql之if条件判断各种使用方式
- 使用HQL语句方式实现多表多条件组合模糊查询
- SQL语句学习,外连接与条件配合使用 (转载)
- 一个数据库查询方法(可以动态设置查询参数,设置查询条件),很巧妙的组合sql语句
- Sql常见问题总结二(Sql语句怎么样查询IP,游标去重复,各种函数使用,各种取时间格式,字符串精确排序,超时锁问题)
- 使用SQL查询语句时,数组动态赋值SQL IN ()作为条件条件一个
- SQL语句中使用变量作为条件。遇到NULL时怎么写
- SQl CASE 语句的嵌套使用方式
- 使用反射让linq实现动态查询, 类似拼接sql语句的where 条件
- Sql常见问题总结二(Sql语句怎么样查询IP,游标去重复,各种函数使用,各种取时间格式,字符串精确排序,超时锁问题)
- NDatabase 入门,简单使用 增删改查。让NDatabase带你脱离ADO.net,各种SQL 语句,各种DBMS,各种CRM,IOC之类的烦恼。我们也不需要仓库设计模式了,你妹的。不要表了,不要设计数据库字段了。就这样!
- SQL Cookbook:一、检索记录(8)在SELECT语句中使用条件逻辑
- 使用T_sql语句向其中一次填入一条数据或一次填入多条数据的方式填入数据。
- 多项查询条件组合下的SQL语句生成
- 多条件组合查询,并根据指定类别找出所有最小子类别的SQL语句备忘
- 在ORACLE中使用SQL语句实现排列组合
- 使用字符串连接的方式来执行Sql语句
- ibatis里面sql语句中条件使用like的写法