mybatis免sql插件之JpaMapper-以Jpa hib
mybatis免sql插件之JpaMapper-以Jpa hibernate的风格写mybatis(生成自定义的MappedStatement)
简介
JpaMapper以Jpa hibernate的风格写mybatis的代码,可以减少手动写sql的烦恼。
优势:
- 不替换底层实现,仅生成sql并交给mybatis
- 方法基本与Jpa hibernate相似,易于框架替换,当然,没那么厉害,不支持联表哦,项目还在继续完善中。
- 提供简单分表功能
- 逻辑简单,可以拿去自己定制
- 提供分页排序功能,最简单的方法实现分页!
gitee地址:https://gitee.com/ffch/JpaMapper
github地址:https://github.com/ffch/jpa-mapper
上篇作为起始篇,介绍一下如何从spring容器中获取到mybatis的mapper/bean。
这一篇将介绍生成自定义的MappedStatement的过程。
mybatis的注解解析MapperAnnotationBuilder
mybatis的注解解析方法位于MapperAnnotationBuilder中。
- parseStatement负责解析每个方法上的sql语句
- buildSqlSourceFromStrings负责生成SqlSource
- MapperBuilderAssistant负责将SqlSource存入mybatis的管理器中。
- handleSelectKeyAnnotation负责处理SelectKey注解,属于主键id回返的策略
当然,里面的方法不止这些,我们需要用的大概就这些了,其他的都是小细节了。
定义自己的解析器JpaMapperAnnotationBuilder
这里就只说主要内容了,其他从简。
-
首先我们需要确定我们的方法类型是属于增删改查的哪一种
-
根据方法名确定我们生成的sql语句
在这之前,我们还是要先拿到mapper接口定义的泛型,并分析泛型类的字段,拿到我们想要的信息,比如字段对应、id字段及策略、分表字段等
生成SqlSource
根据我们前面拿到的信息生成sql,并将sql使用languageDriver.createSqlSource创建mybatis需要的SqlSource。
public static SqlSource createSqlSource(JpaModelEntity jpaModelEntity, Method method, SqlType sqlCommandType,
Class<?> parameterTypeClass, LanguageDriver languageDriver, Configuration configuration) {
try {
String sql = "";
if(jpaModelEntity.isSharding()){
sql = createShardingSql(jpaModelEntity, method, sqlCommandType);
}else{
sql = createCommonSql(jpaModelEntity, method, sqlCommandType);
}
if (StringUtil.isEmpty(sql))
return null;
return languageDriver.createSqlSource(configuration, sql, parameterTypeClass);
} catch (Exception e) {
throw new BuilderException("Could not find value method on SQL annotation. Cause: " + e, e);
}
}
生成Sql
这里仅以findBy + 字段做说明
mybatis查询结果一般作为实体或list返回,所以,findBy操作我们将返回Collection<T>,这个可以不管,写的时候定义什么就是什么。
查询字段
查询字段使用前面分析好的泛型类的字段,使用@Column注解获取数据库字段的名称。因此我们可以生成select的前缀:
select 数据库字段 as 成员名称 , (...)
表名
表名我们使用@Table注解指定。所有我们可以写成:
from 表名
查询条件
findBy + 字段 (and)做查询时,查询条件要把方法名做解析后获得。
String[] params = 方法名.split("And|and|AND");
根据方法名参数,我们可以找到对应的查询条件:
where 条件1(param在实体中的数据库对应名称) = #{实体中的成员名称} and (...)
至此,一个简单的findBy写好了。其他的方法将不再赘述。