简介MyBatis
首先,我们大致介绍一下什么是MyBatis…
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
Mybatis优点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。
- sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射 提供对象关系映射标签,支持对象关系组建维护 提供xml标签,支持编写动态sql。
Paintinglite轻量级框架
框架下载地址
欢迎大家star,following,fork
Paintinglite 2.0下载
在了解什么是MyBatis和MyBatis优点后,我们该介绍今天特别嘉宾,Paintinglite v2.0。这是一款针对移动开发IOS设备数据库管理的框架,在不断迭代中,Paintinglite框架日益完善,性能得到了很大改善。同时,面对J2EE当下在网页后端火热程度,对J2EE两大主流框架Hibernate和MyBatis做了合理化的移植。
为什么选择MyBatis作为2.0版本主打功能???或者说IOS开发为什么要移植J2EE的数据库框架???
答: 小编个人认为在面向对象开发过程中,开发从MVC到MVVC模式的转变是为了更好的维护程序代码。移动端开发虽然不像网页后端开发有大量数据库内容进行操作,但是零散在个个.m文件中的SQL语句在维护起来也变的举步维艰。
首先,选择MyBatis作为2.0主打功能,正是因为它提供了集中式管理SQL语句,解除了SQL与程序代码的耦合。这是IOS现存框架中很难做到的集中管理配置(在小编的认知范围内)。
其次,配置文件或许少了些写代码的乐趣,但是集中式的管理和标签映射使得项目后期维护变得更加简单轻便。
以上两点便是移植J2EE MyBatis框架作为Paintinglite 2.0更新初衷。
PaintingliteXMLSessionManager
提供了集中操作SQL语句的平台,开发者通过定义XML文件就可以简单方便的定义管理整个项目的SQL操作语句
使用方法
XML文件配置规则:
- XML映射文件严格遵守DTD规则,其中提供了,,,,,,,等基本标签;
- XML映射文件需对应表创建的类进行配置(POJO映射);
- XML映射文件格式具有严格要求(v2.0版本对于要求严格);
XML映射文件层级关系
(1) 在进行配置XML映射文件,最外层标签为,mapper标签提供了命名空间namespace;
<mapper namespace="...">
</mapper>
namespace: 表示当前SQL语句操作对象针对的表名称(这里不强制要求namespace内容,建议同操作表名称相同)
(2) 内部就可以进行数据库SQL操作的配置;
select: 查询标签
<select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest">
SELECT * FROM eletest WHERE name = ?
</select>
id: select绑定的ID
resultType: 结果返回类型,目前支持NSDictionary&&NSMutableDictionary | NSArray && NSMutableArray
parameterType: 传入类型(可变参数不需要配置,凡包含obj方法都必须配置parameterType)
select标签内部可以写入查询SQL语句
?: 需要替代部分采用?即可
select: 省略查询
<select id="getEleById" resultType="Eletest" >
?
</select>
当需要使用select * from tableName查询,可以省略SQL语句,通过一个?代替需要写入的SQL语句即可
insert: 插入标签
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Eletest : NSObject
@property (nonatomic,strong)NSNumber *age;
@property (nonatomic,copy)NSString *desc;
@property (nonatomic,copy)NSString *name;
@property (nonatomic,strong)NSNumber *tage;
@property (nonatomic,copy)NSString *teacher;
@end
NS_ASSUME_NONNULL_END
<insert id="getInsertEletest" parameterType="Eletest">
INSERT INTO eletest(name,age,desc,tage,teacher) VALUES (#name,#age,#desc,#tage,#teacher);
</insert>
<insert id="getInsertEletestAuto" parameterType="Eletest">
?
</insert>
id: insert标签绑定ID
parameterType: 传入参数,这里必须配置,为POJO对象的类名称(注意大小写)
#name,#age,#desc,#tage,#teacher: 将插入的值利用“#+类属性名称”构成的组合体进行替代
insert支持省略插入语句,只需要给需要传入的对象设置对应属性值即可
useGeneratedKeys=“true” keyProperty=“ID”: 返回插入的主键值
<insert id="getInsertUserReturnPrimaryKey" parameterType="Eletest" useGeneratedKeys="true" keyProperty="ID">
<selectKey keyProperty="ID" order="AFTER" >
SELECT LAST_INSERT_ID();
</selectKey>
?
</insert>
也可以配置插入返回值
keyProperty=“ID” : 主键值(对应属性值)
order=“AFTER”: 调用时机,可以配置AFTER&&BEFORE
update标签
<update id="getUpdateEle" parameterType="Eletest">
UPDATE eletest SET name = #name and tage = #tage WHERE teacher = #teacher and age = #age;
</update>
id: update标签绑定ID
parameterType: 传入参数,这里必须配置,为POJO对象的类名称(注意大小写)
#name,#age,#tage,#teacher: 将插入的值利用“#+类属性名称”构成的组合体进行替代
update支持省略插入语句,只需要给需要传入的对象设置对应属性值即可
delete标签
<delete id="getDeleteUser" parameterType="Eletest">
DELETE FROM eletest WHERE name = #name and teacher = #teacher and tage = #tage;
</delete>
<delete id="getDeleteEleAuto" parameterType="Eletest">
?
</delete>
id: delete标签绑定ID
parameterType: 传入参数,这里必须配置,为POJO对象的类名称(注意大小写)
#name,#teacher,#tage: 将插入的值利用“#+类属性名称”构成的组合体进行替代
delete支持省略插入语句,只需要给需要传入的对象设置对应属性值即可
XML映射文件高级使用
&&使用
<sql id="eletestSql">id,name,age,teacher,tage,desc</sql>
<select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult">
SELECT <include refid="eletestSql"></include> FROM eletest
</select>
通常操作SQL语句会书写select id,name,age,teacher,tage,desc From eletest字段进行查询,在一个XML映射文件中会用到多次字段名称,可以通过将字段名称包裹,在结合应用。
注意: 使用标签中配置refid传入值必须和配置id相同
动态SQL操作标签
标签
if标签提供了动态判断传入字段值是否为空,条件成立则添加语句,否则不添加语句。
<select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult">
SELECT <include refid="eletestSql"></include> FROM eletest WHERE 1 = 1 AND tage = ? <if test="name != null and name !=''">AND name = ?</if> <if test="desc != null and desc != ''">AND desc = ?</if> <if test="teacher != null and teacher != ''">AND teacher = ?</if>
</select>
<if test="desc != null and desc != ''"></if>
test: 判断条件,目前只支持!=操作
配置标签必须将所有需要判断字段放到最后统一判断书写,为了保证SQL语句正确性,在WHERE后面追加 1 = 1
每一个结构体内需要添加大些的AND
AND desc = ?
标签
where标签消除了if标签必须在WHERE后面添加 1 = 1的限制。同时,省略每一个if结构体内AND
<select id="getEleByObjWhere" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult">
SELECT <include refid="eletestSql"></include> FROM eletest <where><if test="name != null and name !=''">name = ?</if> <if test="desc != null and desc != ''">desc = ?</if> <if test="teacher != null and teacher != ''">teacher = ?</if></where>
</select>
PaintingliteXMLSessionManager 常用方法
/**
* 建立SessionManager
* xmlFileName: 每个类对应一个XML文件,传入XML文件名称
*/
+ (instancetype)buildSesssionManger:(NSString *__nonnull)xmlFileName;
/**
* 查询一个
* methodID: XML绑定的Select ID
* condition: 查询条件
*/
- (NSDictionary *)selectOne:(NSString *__nonnull)methodID condition:(id)condition,... NS_REQUIRES_NIL_TERMINATION;
/* 查询多个 */
- (NSArray<id> *)select:(NSString *__nonnull)methodID condition:(id)condition,... NS_REQUIRES_NIL_TERMINATION;
- (NSArray<id> *)select:(NSString *)methodID obj:(id)obj;
/**
* 插入
* methodID: XML绑定的INSERT ID
* obj: 插入的对象
*/
- (Boolean)insert:(NSString *)methodID obj:(id)obj;
/**
* 插入返回主键ID
* methodID: XML绑定的INSERT ID
* obj: 插入的对象
*/
- (sqlite3_int64)insertReturnPrimaryKeyID:(NSString *)methodID obj:(id)obj;
/**
* 更新
* methodID: XML绑定的INSERT ID
* obj: 插入的对象
*/
- (Boolean)update:(NSString *)methodID obj:(id)obj;
/**
* 删除
* methodID: XML绑定的INSERT ID
* obj: 插入的对象
*/
- (Boolean)del:(NSString *)methodID obj:(id)obj;
实例调用
PaintingliteXMLSessionManager *xmlSessionM = [PaintingliteXMLSessionManager buildSesssionManger:[[NSBundle mainBundle] pathForResource:@"user" ofType:@"xml"]];
[xmlSessionM openSqlite:@"sqlite"];
//查询
NSLog(@"%@",[xmlSessionM selectOne:@"eletest.getEleById" condition:[NSNumber numberWithInt:1],[NSNumber numberWithInt:21],nil]);
NSLog(@"%@",[xmlSessionM select:@"eletest.getEleById" condition:[NSNumber numberWithInt:1],[NSNumber numberWithInt:21], nil]);
Eletest *eletest = [[Eletest alloc] init];
eletest.name = @"CreaterOS";
eletest.age = [NSNumber numberWithInteger:21];
eletest.desc = @"CreaterOS";
eletest.teacher = @"CreaterOS";
eletest.tage = [NSNumber numberWithInteger:21];
NSLog(@"%zd",[[xmlSessionM select:@"eletest.getEleByObj" obj:eletest] count]);
NSLog(@"%zd",[[xmlSessionM select:@"eletest.getEleByObjWhere" obj:eletest] count]);
//插入
[xmlSessionM insert:@"eletest.getInsertEletest" obj:eletest];
NSLog(@"%lu",(unsigned long)[xmlSessionM insertReturnPrimaryKeyID:@"eletest.getInsertUserReturnPrimaryKey" obj:eletest]);
//删除
[xmlSessionM del:@"eletest.getDeleteUser" obj:eletest];
[xmlSessionM del:@"eletest.getDeleteEleAuto" obj:eletest];
//更新
[xmlSessionM update:@"eletest.getUpdateEle" obj:eletest];
框架下载地址
欢迎大家star,following,fork
Paintinglite 2.0下载