在日常工作中,我们时常遇到数据库表中以 (name + code) 为唯一索引, 在数据查询时需要根据这一组条件查询出表中唯一1条数据。
有时,我们的入参是 List<DTO> ,需要进行批量查询数据。那么可以使用以下的SQL来进行数据的查询。由于以下SQL中存在关键字 OR ,Mysql5.0 之前的版本可能会存在索引失效的情况,Mysql5.7版本应该是不存在索引失效的情况。
SELECT
u.id,
u.is_deleted,
u.NAME,
u.age,
u.create_date
FROM
USER u
WHERE
u.is_deleted = 'n'
AND (
( u.NAME = "张三三" AND u.age = 28 )
OR (u.NAME = "李四" AND u.age = 27 )
OR (u.NAME = "李四" AND u.age = 25 )
OR (u.NAME = "王小二" AND u.age = 18 )
)
ORDER BY
u.id DESC,
u.create_date DESC;
在Mybatis项目中,mapper.xml文件中的SQL该如何编写呢? 以下的代码分别是 ServiceImpl.java 文件、mapper.java 文件、 mapper.xml 文件中的代码。
ServiceImpl.java 文件代码
/**
* 以 paramDTO对象集合 批量查询 用户 信息
*
* @param paramDTOList
* @return
*
* @author moon 2023/01/11 15:38
*/
@Override
public List<UserVO> batchSelectUserByParamDTOList(List<UserParamDTO> paramDTOList) {
// 批量查询时,需要对 paramDTOList 进行去重处理,避免查询出重复的数据。 2023/01/11 15:40
paramDTOList = paramDTOList.stream().distinct().collect(Collectors.toList());
return userMapper.batchSelectUserByParamDTOList(paramDTOList);
}
mapper.java 文件代码
/**
* 以 paramDTO对象集合 批量查询 用户 信息
*
* @param paramDTOList
* @return
*
* @author moon 2023/01/11 15:45
*/
List<UserVO> batchSelectUserByParamDTOList(@Param("paramDTOList") List<UserParamDTO> paramDTOList);
mapper.xml 文件代码
<select id="batchSelectUserByParamDTOList" resultType="com.moon.mybatis.vo.UserVO">
SELECT
DISTINCT
u.id,
u.is_deleted,
u.NAME,
u.age,
u.create_date
FROM user u
WHERE
u.is_deleted = 'n'
<if test="paramDTOList != null and paramDTOList.size() != 0">
AND (
<foreach collection="paramDTOList" item="item" separator="OR" index="index">
(
1 = 1
<if test="item.id != null">
AND u.id = #{item.id, jdbcType=BIGINT}
</if>
<if test="item.name != null and item.name != ''">
AND u.NAME = #{item.name, jdbcType=VARCHAR}
</if>
<if test="item.age != null">
AND u.age = #{item.age, jdbcType=BIGINT}
</if>
<if test="item.createDate != null">
AND u.create_date >= #{item.createDate, jdbcType=TIMESTAMP}
</if>
)
</foreach>
)
</if>
ORDER BY u.id DESC, u.create_date DESC
</select>
mapper.xml中SQL编写好后,输入入参参数,即可正常获取到SQL信息。
入参参数如下所示:
[
{
"age":28,
"distinct":false,
"name":"张三三"
},
{
"age":27,
"distinct":false,
"name":"李四"
},
{
"age":25,
"distinct":false,
"name":"李四"
},
{
"age":25,
"distinct":false,
"name":"李四"
},
{
"age":18,
"distinct":false,
"name":"王小二"
}
]
在 knife4j 接口文档中测试
调用接口后的log日志如下所示,小伙伴们可以将日志复制出来,自己仔细观看,在Navicat中运行一下看看。
2023-01-11 17:26:20.702 INFO 14780 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-01-11 17:26:20.702 INFO 14780 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-01-11 17:26:20.712 INFO 14780 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms
2023-01-11 17:26:21.549 TRACE 14780 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to springfox.documentation.swagger.web.ApiResourceController#swaggerResources()
2023-01-11 17:26:21.549 TRACE 14780 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to springfox.documentation.swagger.web.ApiResourceController#uiConfiguration()
2023-01-11 17:26:30.143 TRACE 14780 --- [nio-8080-exec-4] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.moon.mybatis.controller.UserController#selectUser2(List, Integer, Integer)
2023-01-11 17:26:30.209 INFO 14780 --- [nio-8080-exec-4] c.m.mybatis.controller.UserController : 以paramDTO集合对象批量查询用户信息, 传入的参数页码为:1, 页大小:20, paramDTO对象集合为:[{"age":28,"distinct":false,"name":"张三三"},{"age":27,"distinct":false,"name":"李四"},{"age":25,"distinct":false,"name":"李四"},{"age":25,"distinct":false,"name":"李四"},{"age":18,"distinct":false,"name":"王小二"}]
2023-01-11 17:26:30.262 DEBUG 14780 --- [nio-8080-exec-4] c.m.m.m.U.batchSelectUserByParamDTOList : ==> Preparing: SELECT DISTINCT u.id, u.is_deleted, u.NAME, u.age, u.create_date FROM user u WHERE u.is_deleted = 'n' AND ( ( 1 = 1 AND u.NAME = ? AND u.age = ? ) OR ( 1 = 1 AND u.NAME = ? AND u.age = ? ) OR ( 1 = 1 AND u.NAME = ? AND u.age = ? ) OR ( 1 = 1 AND u.NAME = ? AND u.age = ? ) ) ORDER BY u.id DESC, u.create_date DESC
2023-01-11 17:26:30.263 DEBUG 14780 --- [nio-8080-exec-4] c.m.m.m.U.batchSelectUserByParamDTOList : ==> Parameters: 张三三(String), 28(Integer), 李四(String), 27(Integer), 李四(String), 25(Integer), 王小二(String), 18(Integer)
2023-01-11 17:26:30.267 DEBUG 14780 --- [nio-8080-exec-4] c.m.m.m.U.batchSelectUserByParamDTOList : <== Total: 3
讲到这里,差不多就结束了。然而,以 paramDTO对象集合 形式进行批量查询是存在一些小坑的。在测试用例数据中,我特意写了2组重复的数据,在 ServiceImpl.java 文件中,我对 paramDTOList 进行了去重处理,在 mapper.xml 中,我也进行了去重处理, 这都是为什么呢???
大家可以观看我下一篇文章: Mybatis以 paramDTO对象集合 进行批量查询去重问题
Swagger 接口文档访问地址为:http://localhost:8080/doc.html#/home
本案例项目Demo地址为: Mybatis框架学习 ,MyBatis-SpringBoot 项目。
如果大家觉得我的项目还行,可以加一个 Start ,感谢各位老铁了。