mybatis-dynamic-query 3.0 更新
项目地址: mybatis-dynamic-query
前言
在 2.0 完成对 tk.mapper 集成,为何 mybatis-dynamic-query 选择 tk.mapper 集成, 再 3.0 进一步对查询进行优化,当然这里可能会对比 mybatis-plus, 我觉得有对比大家才能选择自己合适的。
更新内容
- 添加 DynamicQueryBuilder 步骤化生成 DynamicQuery 语句
- 优化 DynamicQuery 添加,移除筛选和排序
DynamicQueryBuilder 引入
这个在 3.0 引入,目的是为了让大家写查询的时候真的像写 sql (严格遵循 sql 查询顺序),最后通过 build 方法来 build 一个 DynamicQuery, 根据经验来看 DynamicQueryBuilder 适合筛选条件已知的情况下。
public List<ProductsDO> getProductListByBuilder() {
// select product_name, list_price, category
// where (list_price > 1 and list_price < 10) and description is not null or id = 1
// order by id desc, list_price asc
DynamicQuery<ProductsDO> query = DynamicQueryBuilder.create(ProductsDO.class)
.select(ProductsDO::getProductName, ProductsDO::getListPrice, ProductsDO::getCategory)
.where(ProductsDO::getListPrice, greaterThan(BigDecimal.ONE),
and(ProductsDO::getListPrice, lessThan(BigDecimal.TEN)))
.and(ProductsDO::getDescription, notEqual(null))
.or(ProductsDO::getId, isEqual(1))
.orderBy(ProductsDO::getId, desc())
.thenBy(ProductsDO::getListPrice, asc())
.build();
return productMapper.selectByDynamicQuery(query);
}
DynamicQuery 筛选排序优化
DynamicQuery 的很多方法名被改了,和 DynamicQueryBuilder 基本保持一致,这样大家在使用的时候比较方便,从下面的例子大家可以看到可以在任何位置添加筛选或者排序并且和 if 判断语句结合
@Test
public void testGetProductListByQuery() {
BigDecimal startPrice = BigDecimal.valueOf(1.1);
BigDecimal endPrice = BigDecimal.valueOf(10.1);
DynamicQuery<ProductsDO> query = DynamicQuery.createQuery(ProductsDO.class)
.select(ProductsDO::getProductName, ProductsDO::getListPrice, ProductsDO::getCategory);
// 根据参数添加筛选条件,这里就是我们看看开始价,结束价有没有,如果有才会放到一个组里面,
if (Objects.nonNull(startPrice) || Objects.nonNull(endPrice)) {
FilterGroupDescriptor<ProductsDO> priceFilterGroup = new FilterGroupDescriptor<>();
if (Objects.nonNull(startPrice)) {
priceFilterGroup.and(ProductsDO::getListPrice, greaterThan(startPrice));
}
if (Objects.nonNull(endPrice)) {
priceFilterGroup.and(ProductsDO::getListPrice, lessThan(endPrice));
}
}
query.and(ProductsDO::getDescription, notEqual(null))
.or(ProductsDO::getId, isEqual(1))
.orderBy(ProductsDO::getId, desc())
.orderBy(ProductsDO::getListPrice, asc());
List<ProductsDO> result = productMapper.selectByDynamicQuery(query);
Assert.assertFalse(result.isEmpty());
}
enable 字段
大家看到上面例子, 有 if 判断条件会断开一个查询,这个在阅读的时候非常不方便,有了 enable 可以设置这个筛选是否生效,这样我们写代码的可读性高了
@Test
public void testGetProductListByQuery2() {
BigDecimal startPrice = BigDecimal.valueOf(1.1);
BigDecimal endPrice = BigDecimal.valueOf(10.1);
// 根据参数添加筛选条件,这里就是我们看看开始价,结束价有没有,如果有才会放到一个组里面,
DynamicQuery<ProductsDO> query = DynamicQuery.createQuery(ProductsDO.class)
.select(ProductsDO::getProductName, ProductsDO::getListPrice, ProductsDO::getCategory)
.and(group -> group
.and(ProductsDO::getListPrice, greaterThan(startPrice), Objects.nonNull(startPrice))
.and(ProductsDO::getListPrice, lessThan(endPrice), Objects.nonNull(endPrice)))
.and(ProductsDO::getDescription, notEqual(null))
.or(ProductsDO::getId, isEqual(1))
.orderBy(ProductsDO::getId, desc())
.orderBy(ProductsDO::getListPrice, asc());
List<ProductsDO> result = productMapper.selectByDynamicQuery(query);
Assert.assertFalse(result.isEmpty());
}
对比
开始我是不知道 mybatis-plus 博客园动态查询第一帖 的不然的话,可能我就直接用了哈哈~,既然自己做了一个也和标杆对比一下吧,但还是期望大家选择自己合适的吧,这里我只对比 mybatis-plus 查询功能。
举例
复杂条件查询
基本和动态查询在写法上基本表现一致,不过新版的动态插叙加上了 enable 字段以后读起来会好一些
@Test
public void testGetProductListByPlus() {
BigDecimal startPrice = BigDecimal.valueOf(1.1);
BigDecimal endPrice = BigDecimal.valueOf(10.1);
LambdaQueryWrapper<ProductsDO> queryWrapper = new QueryWrapper<ProductsDO>().lambda()
.select(ProductsDO::getListPrice, ProductsDO::getProductName, ProductsDO::getCategory);
if (Objects.nonNull(startPrice) && Objects.nonNull(endPrice)) {
// 没有找到如何将连个price 筛选放到一个组里面
queryWrapper.and(obj -> obj.gt(ProductsDO::getListPrice, startPrice)
.lt(ProductsDO::getListPrice, endPrice));
} else if (Objects.nonNull(startPrice)) {
queryWrapper.gt(ProductsDO::getListPrice, startPrice);
} else if (Objects.nonNull(endPrice)) {
queryWrapper.lt(ProductsDO::getListPrice, startPrice);
}
queryWrapper.ne(ProductsDO::getDescription, null)
.or(obj -> obj.eq(ProductsDO::getId, 1))
.orderByDesc(ProductsDO::getId)
.orderByAsc(ProductsDO::getListPrice);
List<ProductsDO> result = productPlusMapper.selectList(queryWrapper);
Assert.assertFalse(result.isEmpty());
}
灵活性
mybatis-plus 是非常灵活的, api 特别多, 比如 queryWrapper 可以直接接上操作符比如 eq,gt, lt 也可以接 and, or, 但是动态查询对于筛选只能接 and / or 操作符必须在里面, 我个人喜欢统一性,这其实就是仁者见仁智者见智了。
安全性
类型检查
可以说这个就是动态查询的优势了,设计之初就是怎么样让用户写出不会错的代码,所以所有的筛选值都是强类型,比如说字段 Price 是一个 BigDecimal, 如果写 Integer 就会报错,但是 mybatis-plus 就不会报错。
@Test
public void testGetProductListByQuery2() {
BigDecimal startPrice = BigDecimal.valueOf(1.1);
BigDecimal endPrice = BigDecimal.valueOf(10.1);
Integer integerStartPrice = 1;
DynamicQuery<ProductsDO> query = DynamicQuery.createQuery(ProductsDO.class)
.select(ProductsDO::getProductName, ProductsDO::getListPrice, ProductsDO::getCategory)
.and(group -> group
// 这段代码 会包错,因为integerStartPrice 不是BigDecimal 类型的
.and(ProductsDO::getListPrice, greaterThan(integerStartPrice), Objects.nonNull(startPrice))
.and(ProductsDO::getListPrice, lessThan(endPrice), Objects.nonNull(endPrice)))
.and(ProductsDO::getDescription, notEqual(null))
.or(ProductsDO::getId, isEqual(1))
.orderBy(ProductsDO::getId, desc())
.orderBy(ProductsDO::getListPrice, asc());
List<ProductsDO> result = productMapper.selectByDynamicQuery(query);
Assert.assertFalse(result.isEmpty());
}
链式调用
这个动态查询和 mybatis-plus 都是支持的,不一样的是,动态查询不会随意接后面的方法,是做过验证的,但是 mybatis-plus 比较灵活,把这个安全性检查交给用户了。
比如
@Test
public void testGetProductListByPlus() {
BigDecimal startPrice = BigDecimal.valueOf(1.1);
BigDecimal endPrice = BigDecimal.valueOf(10.1);
LambdaQueryWrapper<ProductsDO> queryWrapper = new QueryWrapper<ProductsDO>().lambda()
.select(ProductsDO::getListPrice, ProductsDO::getProductName, ProductsDO::getCategory);
if (Objects.nonNull(startPrice) && Objects.nonNull(endPrice)) {
// 这里我随意在筛选后面添加了一个排序, 编译的时候没有错,执行的时候会报错
queryWrapper.and(obj -> obj.gt(ProductsDO::getListPrice, startPrice)
.lt(ProductsDO::getListPrice, endPrice).orderByAsc(ProductsDO::getListPrice));
} else if (Objects.nonNull(startPrice)) {
queryWrapper.gt(ProductsDO::getListPrice, startPrice);
} else if (Objects.nonNull(endPrice)) {
queryWrapper.lt(ProductsDO::getListPrice, startPrice);
}
queryWrapper.ne(ProductsDO::getDescription, null)
.or(obj -> obj.eq(ProductsDO::getId, 1))
.orderByDesc(ProductsDO::getId)
.orderByAsc(ProductsDO::getListPrice);
List<ProductsDO> result = productPlusMapper.selectList(queryWrapper);
Assert.assertFalse(result.isEmpty());
}
小结
主要给大家看了一下 3.0 对查询的改动,主要也是给大家多一个选择, 稍微对比了一下 mybatis-plus, 自我感觉在查询写法上面有优势,但是 mybatis-plus 是功能非常多,大而全的一整套解决方案,文档非常完善,这也是动态查询不具备的,所以大家选择自己合适的。
mybatis-dynamic-query 3.0 更新的更多相关文章
- Mybatis Dynamic Query 2.0.2
项目地址:https://github.com/wz2cool/mybatis-dynamic-query 文档地址:https://wz2cool.gitbooks.io/mybatis-dynam ...
- Mybatis Dynamic Query 1.0.2版本
项目地址:https://github.com/wz2cool/mybatis-dynamic-query 文档地址:https://wz2cool.gitbooks.io/mybatis-dynam ...
- Mybatis Dynamic Query 2.0 入门
简介 2.0 昨天打包好了,主要是整合了tk.mybatis.mapper 到项目中去,所以和1.x比起来主要多了一个通用mapper.因为作者主要是使用springboot 这里讲一下Springb ...
- Mybatis Dynamic Query 框架整合
项目地址:https://github.com/wz2cool/mybatis-dynamic-query 文档地址:https://wz2cool.gitbooks.io/mybatis-dynam ...
- Mybatis Dynamic Query 更新
文章目录 1. 简介 2. 准备工作 3. 开始更新 3.1. update 3.2. update Null 4. 结束 5. 关注@我 项目地址:https://github.com/wz2coo ...
- Mybatis Dynamic Query 简单筛选
在框架中,筛选描述类有两种(FilterDescriptor, FilterGroupDescriptor),这里我们主要举例来说明FilterDescriptor用法. FilterDescript ...
- [Liferay6.2]Liferay Dynamic Query API示例
介绍 Liferay提供了几种方法定义复杂的查询用来检索数据库中的数据. 通常情况下,在每个service Entity中,通过定义一些'finder'方法,可以便捷地满足基本的数据查询操作. 但是, ...
- Mybatis分页插件2.0版本号公布
项目地址:http://git.oschina.net/free/Mybatis_PageHelper 软件介绍:http://www.oschina.net/p/mybatis_pagehelper ...
- mybatis学习之路----批量更新数据两种方法效率对比
原文:https://blog.csdn.net/xu1916659422/article/details/77971696/ 上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方 ...
- 【mybatis】mybatis中批量插入 批量更新 batch 进行insert 和 update,或者切割LIst进行批量操作
================================================================== 分别展示 mybatis 批量新增 和 批量更新 的操作: ...
随机推荐
- Spring框架之JdbcTemplate
Spring框架之JdbcTemplate 一.JdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到Jd ...
- 并发新特性—Executor框架与线程池
http://blog.csdn.net/ns_code/article/details/17465497 Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的AP ...
- Windows GIT SSH 免密教程
Windows GIT SSH 免密教程 安装git客户端,最新下载地址如下 https://github.com/git-for-windows/git/releases/download/v2.2 ...
- HTML(七)CSS
一个实例 <!DOCTYPE html> 菜鸟教程(runoob.com) body { background-color:#d0e4fe; } h1 { color:orange; te ...
- codeforces 1041 E. Tree Reconstruction 和度数有关的构造树
CF 1041E:http://codeforces.com/contest/1041/problem/E 题意: 告诉你一个树的节点个数,显然有n-1条边.已知去掉一条边后,两个集合中最大的节点值. ...
- Atcoder E - Meaningful Mean(线段树+思维)
题目链接:http://arc075.contest.atcoder.jp/tasks/arc075_c 题意:问数组a有多少子区间平均值为k 题解:一开始考虑过dp,但是显然不可行,其实将每一个数都 ...
- lightoj 1074 - Extended Traffic(spfa+负环判断)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1074 题意:有n个城市,每一个城市有一个拥挤度ai,从一个城市I到另一个城市J ...
- 利用GPU训练网络时遇到的一些问题
1. OSError: [Error 12] Cannot allocate memory 解决办法: 出现这个错误时我是绝望的...因为我看了别人的解决办法,要加内存条才能解决...但是我不甘心,想 ...
- Fire Balls 08——音效的添加
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
- 【Spring】AOP注解方式实现机制
一.概述 二.@EnableAspectJAutoProxy 注解分析 三.分析AnnotationAwareAspectJAutoProxyCreator 四.执行流程 1. registerBea ...