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 批量新增 和 批量更新 的操作: ...
随机推荐
- Delphi - 创建text文件并添加数据到文件中
创建文本文件 代码如下: //创建一个文本文件 procedure CreateTextFile(); var AssignFile(TF,'C:\tmp\1.txt'); ReWrite(TF); ...
- .net中DES加密算法研究
/// <summary> /// DES加密算法 /// </summary> /// <param name="toEncrypt">要加密 ...
- hdu6312 2018杭电多校第二场 1004 D Game 博弈
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- Postgresql-rman
联机程序. 并且目标数据库必须处于归档模式. 支持在线全备, 增量备份, 归档备份 增量备份基于已经存在的一个全库备份 rman 本身使用pg_start_backup(), copy, pg_sto ...
- Java复习笔记(二):数据类型以及逻辑结构
一.数据类型 1.数据类型又分为基本数据类型和引用数据类型,而他们的区别在于,引用数据类型需要开辟内存空间来进行分配,什么意思呢?先来看看他们有哪些. 整数型:byte,short,int,long ...
- zabbix -- 学习之一
网上说这东西是运维必须学会的东西,于是乎捣鼓的第一步就开始了. 首先,在度娘上搜索了一下,找到了官网,按照官网的说法没操作成功.后来照这博主的帖子(https://www.cnblogs.com/xi ...
- 014 Python基本图形绘制小结
目录 一.Python基本语法元素 1.1 温度转换 二.Python基本图形绘制 2.1 Python蟒蛇绘制 一.Python基本语法元素 缩进.注释.命名.变量.保留字 数据类型.字符串. 整数 ...
- git修改user.name 和user.email
今天刚刚入门了下git,,然后初始化的时候将用户名弄错了...就很气啊.然后网上找了半天都找不出一个可靠的修改全局用户名和邮箱的方法.. 最后还是自己摸索出来了..其实也很简单. 首先进入gi ...
- Django-开放静态资源-获取请求携带的数据-pychram连接数据库-修改Django默认数据库-DjangoORM操作--表管理-记录管理-01
目录 关于静态资源访问 为什么要配置静态文件才能获取静态资源 常见的静态文件种类 如何配置来开启访问权限 禁用浏览器缓存 django的自动重启机制(热启动) 静态文件接口动态解析 向服务器发送数据 ...
- Docker下dubbo开发三部曲之三:java开发
在前两章<Docker下dubbo开发,三部曲之一:极速体验>和<Docker下dubbo开发,三部曲之二:本地环境搭建>中,我们体验了dubbo环境搭建以及服务的发布和消费, ...