源码解读Mybatis List列表In查询实现的注意事项
在SQL开发过程中,动态构建In集合条件查询是比较常见的用法,在Mybatis中提供了foreach功能,该功能比较强大,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。下面是一个演示示例:
<select id="findByIdsMap" resultMap="BaseResultMap">
Select
<include refid="Base_Column_List" />
from jria where ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
但由于官方文档对这块的使用,描述的比较简短,细节上也被忽略掉了(可能是开源项目文档一贯的问题吧),也使用不少同学在使用中遇到了问题。特别是foreach这个函数中,collection属性做什么用,有什么注意事项。由于文档不全,这块只能通过源代码剖析的方式来分析一下各个属性的相关要求。
collection属性的用途是接收输入的数组或是List接口实现。但对于其名称的要求,Mybatis在实现中还是有点不好理解的,所以需要特别注意这一点。
下面开始分析源代码(笔记使用的是Mybatis 3.0.5版本)
先找到Mybatis执行SQL配置解析的入口
MapperMethod.java类中 public Object execute(Object[] args) 该方法是执行的入口.
针对in集合查询,对应用就是 selectForList或SelctForMap方法。
但不管调用哪个方法,都会对原来JDK传入的参数 Object[]类型,通过 getParam方法转换成一个Object,那这个方法是做什么的呢?分析源码如下:
上图中标红的两处,很惊讶的发现,一个参数与多个参数的处理方式是不同的(后续很多同学遇到的问题,就有一大部分出自这个地方)。如果参数个数大于一个,则会被封装成Map, key值如果使用了Mybatis的 Param注解,则会使用该key值,否则默认统一使用数据序号,从1开始。这个问题先记下,继续分析代码,接下来如果是selectForList操作(其它操作就对应用相应方法),会调用DefaultSqlSession的public List selectList(String statement, Object parameter, RowBounds rowBounds) 方法
又一个发现,见源代码如下:
上图标红部分,对参数又做了一次封装,我们看一下代码
现在有点清楚了,如果参数类型是List,则必须在collecion中指定为list, 如果是数据组,则必须在collection属性中指定为 array.
现在就问题就比较清楚了,如果是一个参数的话,collection的值取决于你的参数类型。
如果是多个值的话,除非使用注解Param指定,否则都是数字开头,所以在collection中指定什么值都是无用的。下图是debug显示结果。
针对上面分析的结果,下面给出了一个使用的解决方案,希望对大家对帮助。
在使用这个功能是需要特别注意以下规则:
1. 当查询的参数只有一个时
findByIds(List<Long> ids)
1.a 如果参数的类型是List, 则在使用时,collection属性要必须指定为 list
<select id="findByIdsMap" resultMap="BaseResultMap">
Select
<include refid="Base_Column_List" />
from jria where ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
findByIds(Long[] ids)
1.b 如果参数的类型是Array,则在使用时,collection属性要必须指定为 array
<select id="findByIdsMap" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from jria where ID in
<foreach item="item" index="index" collection="array"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
2. 当查询的参数有多个时,例如 findByIds(String name, Long[] ids)
这种情况需要特别注意,在传参数时,一定要改用Map方式, 这样在collection属性可以指定名称
下面是一个示例
Map<String, Object> params = new HashMap<String, Object>(2);
params.put("name", name);
params.put("ids", ids);
mapper.findByIdsMap(params);
<select id="findByIdsMap" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from jria where ID in
<foreach item="item" index="index" collection="ids"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
完整的示例如下:
例如有一个查询功能,Mapper接口文件定义如下方法:
List<Jria> findByIds(Long... ids);
使用 in 查询的sql拼装方法如下:
<select id="findbyIds" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from jria where ID in
<foreach item="item" index="index" collection="array"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
注:本文转载自http://www.blogjava.net/xmatthew/archive/2011/08/31/355879.html
源码解读Mybatis List列表In查询实现的注意事项
分享到:
相关推荐
Mybatis批量插入更新xml方式和注解方式的方法实例 Mybatis是一款流行的持久层框架,它提供了多种方式来实现批量插入和更新操作。今天,我们将介绍Mybatis批量插入更新xml方式和注解方式的方法实例。 Mybatis批量...
总结来说,批量插入数据的Mapper配置文件写法主要包括以下步骤: 1. 在Mapper接口中定义一个接受List类型参数的方法。 2. 在Mapper XML文件中,使用`<insert>`标签定义插入语句,设置`useGeneratedKeys="true"`以便...
MyBatis PostgreSQL 批量删除操作方法 MyBatis 是一个基于 Java 的持久层框架,它提供了一个简单的方式来交互数据库。在本文中,我们将介绍如何使用 MyBatis 实现 PostgreSQL 批量删除操作。 PostgreSQL 简介 ...
MyBatis是一个强大的持久层框架,它允许开发者编写SQL查询,使用存储过程,并进行高级映射,无需手动处理JDBC代码和结果集的封装。在处理大量数据时,批量插入是一种提高性能的有效策略。本文将深入探讨MyBatis中...
- 自动完成单表CRUD操作(包括简单的单个对象插入、查询、更新、删除操作和批量操作)。 - 提供分页插件,支持自动分页和自定义SQL分页查询。 - 支持Spring环境下根据不同环境加载不同的配置。 - 提供代码自动...
详解MyBatis常用写法 MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生...
MyBatis模糊查询like语句的写法相对简单,只需要在占位符中加入%即可。 在DAO接口的工作原理方面,MyBatis通过动态代理生成接口的代理实例。Dao接口里方法参数不同时,方法可以重载,MyBatis通过动态代理和反射技术...
- MyBatis通过Mapper XML文件来定义SQL语句,可以灵活控制SQL的写法和参数绑定。 - `<select>`:定义查询语句,可以返回结果集。 - `<insert>`:定义插入语句,支持自动获取自增主键。 - `<update>`:定义更新...
在本项目"springboot-mybatis-custom-language-driver.zip"中,主要探讨了如何在SpringBoot集成MyBatis的环境中,自定义语言驱动以实现更灵活的SQL动态查询功能,特别是循环查询、IN查询以及if条件判断的动态SQL语句...
在"Digital-Assets-Manag-mybatis动态sqldemo"中,我们可以看到如何利用这些动态SQL标签来处理数字资产的查询、更新和删除等操作。例如,当需要根据多种条件筛选数字资产时,可以使用`<if>`标签判断条件是否成立,...
它允许开发者通过更简洁的方式定义复杂的查询和更新操作,减少了XML配置文件的繁琐工作。例如,它可以支持动态SQL的内联写法,使得在Java代码中直接构建SQL变得更加直观。此外,它还提供了注解方式来定义Mapper接口...
* 不适合复杂查询:MyBatis 不适合复杂的查询,需要使用其他框架来实现复杂的查询。 MyBatis 框架适用场合 MyBatis 框架适用于: * 小型到中型项目:MyBatis 适用于小型到中型项目,能够满足大多数的数据库访问...
- Mybatis-Plus 支持自动填充创建时间和更新时间等公共字段,只需要在实体类的字段上使用 `@TableField(fill = FieldFill.INSERT/UPDATE)` 注解即可。 8. **逻辑删除**: - 通过 `@TableLogic` 注解,你可以实现...
8. MyBatis模糊查询的SQL写法。 9. MyBatis中的Dao接口是如何工作的,以及其参数不同的方法是否能重载。 10. MyBatis的分页实现以及分页插件的工作原理。 11. SQL执行结果封装成对象的映射方式。 12. 如何执行批量...
2. **批处理**: 批量插入、更新或删除操作可以显著提高性能。 3. **延迟加载(Lazy Loading)**: 只在真正需要时加载关联对象,避免不必要的数据传输。 4. **预加载(Eager Loading)**: 反之,如果关联对象经常...
1. **MyBatis 的定义及优点**:MyBatis 是一个支持定制化 SQL、存储过程以及高级映射的优秀持久层框架。它的优点包括简化数据库操作代码、高度可定制化、支持动态 SQL 语句、以及提供 XML 或注解两种方式来配置 SQL ...
比如,模糊查询like语句的写法,以及分页查询的实现,MyBatis的分页插件原理等。 4. **ORM框架**:MyBatis的映射方式包括Map映射、注解映射和XML映射,面试中可能会要求解释它们是如何将SQL结果封装为目标对象并...
8. **模糊查询的写法**: - 可以使用 ${ } 中进行字符串拼接。 9. **Dao接口的工作原理**: - MyBatis通过动态代理来创建Mapper接口的代理对象。 10. **MyBatis分页**: - 可以使用RowBounds或分页插件,如...
- MyBatis定义:MyBatis是一个支持定制化SQL、存储过程以及高级映射的优秀持久层框架,是Java持久层框架的一种半自动ORM实现。 - 优点:简化了代码编写,提供了灵活性,易于与第三方数据处理框架集成,SQL语句与...