Mybatis Dynamic Query 框架整合
项目地址:https://github.com/wz2cool/mybatis-dynamic-query
文档地址:https://wz2cool.gitbooks.io/mybatis-dynamic-query-zh-cn/content/
博客文章:https://wz2cool.github.io/tags/Mybatis-Dynamic-Query/
初入 JAVA
因为工作关系,开始接触 JAVA(但心中一直割舍不下我大.net)。一开始选择持久化框架的时候,同事选的是 Mybatis,开始我还闹情绪,感觉应该选 hibernate,因为以前用 EntityFramework 感觉还不错。关键是入 JAVA 不久,算了就用 Mybatis 吧,也算是误打误撞才有了这个动态查询框架。
Mybatis 震撼
如果说 hibernate 是全自动的,那么 Mybatis 就是半自动。Mybatis 比 hibernate 更强的在于他对 sql 的控制更加好,hibernate 这些 ORM 生成的 sql 在调优的时候比较麻烦,当然你们可以说使用 hibernate 照样可以写 sql,嗯是可以的,但是把一块 sql 写到了 code 里面而且还是 String 类型, 以后改个什么字段找半天(如果有不对,请大家指出)。
Mybatis 有个专门的 xml 文件放 sql 语句,这个其实很不错,至少不用去 code 里面找 sql。 其实 Mybatis 是提供了一些根据条件生成对应的 sql 比如 <if> <foreach> 标签。
动态查询框架初衷
在实际应用 Mybatis 的时候,我们同样遇到了问题,就是 xml 接口数量爆炸的情况,而且 XML 代码量大了,也不是非常好维护,XML 也是一种没有强类型的语言。 嗯 这个就是我们的框架建立的最初目的。
灵感的爆发同样来自于我大.net, 其实你们如果用过 RIA service 就知道 FilterDescriptor 哈哈,确实借鉴了一下 参考: https://msdn.microsoft.com/en-us/library/system.windows.controls.filterdescriptor(v=vs.91).aspx
框架解决了什么问题
- 不必写大量的代码在 XML 中,因为这些代码都是弱类型的。
- 筛选排序是被 Java 代码中维护,可以进行组合使用。
- 你的筛选排序是可以热更新的,在代码中想什么时候加就什么时候加。
- 你的筛选条件是可以被持久化的,可以作为配置保存下来。
框架基本组织
interface
一个实体的基本操作定义
@Mapper
public interface NorthwindDao {
List<Product> getProductByDynamic(Map<String, Object> params);
<span class="hljs-type">int</span> <span class="hljs-title function_">insert</span><span class="hljs-params">(Map<String, Object> params)</span>;
<span class="hljs-type">int</span> <span class="hljs-title function_">update</span><span class="hljs-params">(Map<String, Object> params)</span>;
<span class="hljs-type">int</span> <span class="hljs-title function_">delete</span><span class="hljs-params">(Map<String, Object> params)</span>;
}
xml 基本格式
xml 中与之对应的实现
<!-- 增加 -->
<insert id="insert" parameterType="java.util.Map">
${insertExpression}
</insert>
<!-- 删除 -->
<delete id="delete" parameterType="java.util.Map">
${deleteExpression}
</delete>
<!-- 修改 -->
<update id="update" parameterType="java.util.Map">
${updateExpression}
</update>
<!-- 查询 -->
<select id="getProductByDynamic" parameterType="java.util.Map"
resultType="com.github.wz2cool.dynamic.mybatis.db.model.entity.table.Product">
SELECT * FROM product
<if test="whereExpression != null and whereExpression !=''">WHERE ${whereExpression}</if>
<if test="orderExpression != null and orderExpression !=''">ORDER BY ${orderExpression}</if>
</select>
参数 Map 里面是什么
这里用一张图来说明
- 蓝色背景里面都是我们的动态表达式,注意里面参数都是占位符(比如 #{id_placeholder}).
- 绿色背景都是我们占位符的与之对应的实际数据
调用
简单写一个查询的例子
@Test
public void testEqual() throws Exception {
FilterDescriptor idFilter =
new FilterDescriptor(FilterCondition.AND, "productID", FilterOperator.EQUAL, 2);
<span class="hljs-type">ParamExpression</span> <span class="hljs-variable">paramExpression</span> <span class="hljs-operator">=</span> mybatisQueryProvider.getWhereExpression(ProductView.class, idFilter);
Map<String, Object> queryParams = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();
queryParams.putAll(paramExpression.getParamMap());
queryParams.put(<span class="hljs-string">"whereExpression"</span>, paramExpression.getExpression());
<span class="hljs-type">ProductView</span> <span class="hljs-variable">productView</span> <span class="hljs-operator">=</span>
northwindDao.getProductViewsByDynamic(queryParams).stream().findFirst().orElse(<span class="hljs-literal">null</span>);
assertEquals(Long.valueOf(<span class="hljs-number">2</span>), productView.getProductID());
}
杂谈
- 在做这个框架也会去看别人写的 Mybatis 框架,其中就有Mybatis-jpa, 和博主交谈以后发现我这边少了 jdbcType 在 insert 和 update 中,果然和需要交流,当然这个会再 1.0.2 版本解决具体 bug
- 在写文档的时候, 有次推翻了原来的想法,坑啊,全部 testCase 重写 T_T,坚持保持 100% 代码覆盖。
- 跨出开源第一步,代码、文档在一点点完善,虽然比不上大神的 NB 框架,至少第一步迈出去了。
- 希望大家多多关注,批评也可以,毕竟 java 功底不深,欢迎指教。
文章整合
Mybatis Dynamic Query 简单筛选
Mybatis Dynamic Query 组筛选
Mybatis Dynamic Query 排序
Mybatis Dynamic Query 筛选 + 排序
Mybatis Dynamic Query 插入
Mybatis Dynamic Query 更新
Mybatis Dynamic Query 删除
Mybatis Dynamic Query 属性表达式
Mybatis Dynamic Query join 视图
关注我 ##
最后大家可以关注我和 Mybatis-Dynamic-query 项目 _
Follow @wz2cool Star Fork