mybatis collection
转自:http://blog.csdn.net/wj3319/article/details/9025349
在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>
mybatis collection的更多相关文章
- mybatis collection 一对多关联查询,单边分页的问题总结!
若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...
- mybatis collection的使用
Mybatis collection的使用 今天学习了mybatis中的collection使用,作为记录以后使用.首先看一下javabean的结构! public class Article { ...
- Mybatis Collection查询集合只出现一条数据
1.原因 如果两表联查,主表和明细表的主键都是id的话,明细表的多条只能查询出来第一条. 2.解决办法 级联查询的时候,主表和从表有一样的字段名的时候,在mysql上命令查询是没问题的.但在mybat ...
- MyBatis collection的两种形式——MyBatis学习笔记之九
与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...
- mybatis <collection>标签 类型为string时无法获取重复数据错误
1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...
- mybatis collection标签和association标签(一对多,一对一)转载
mybatis 一对一与一对多collection和association的使用 在mybatis如何进行一对一.一对多的多表查询呢?这里用一个简单的例子说明. 一.一对一 1.associati ...
- MyBatis Collection小记—— 关联查询、递归查询、多字段关联
经常会用到mybatis的Collection标签来做级联查询或递归查询,现通过一个伪例来简单的说明一下使用中的关键点: 首先先列出三个表,给出一个场景: 1,角色表 t_role( id,name ...
- mybatis collection解析以及和association的区别
1.collection标签 说到mybatis的collection标签,我们肯定不陌生,可以通过它解决一对多的映射问题,举个例子一个用户对应多个系统权限,通过对用户表和权限表的关联查询我们可以得到 ...
- mybatis collection使用注意
背景 今天我在使用collection时候,出现数据库有两条数据,但是却返回一条,在复制这条数据到四条后,依然返回一条 分析 这四条数据,数据库的每个字段值完全相同,所以估计是当成一条处理了 如果随便 ...
随机推荐
- 七、Flex 布局
布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C 提出了一种新 ...
- 英特尔vPro博锐技术激活
英特尔vPro博锐技术激活 参考: Intel官方Management Engine BIOS Extension (Intel®MEBX)手册:http://www.intel.com/conten ...
- 如何使 JavaScript 更高效?
传统的 Web 页面不会包含很多脚本,至少不会太影响 Web 页面的性能.然而,Web 页面变得越来越像应用程序,脚本对其的影响也越来越大.随着越来越多的应用采用 Web 技术开发,脚本性能的提升就变 ...
- 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句
salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...
- openssh升级
转载:(感谢作者) centos7 升级openssh到openssh-8.0p1版本 https://www.cnblogs.com/nmap/p/10779658.html centos 7 op ...
- Windows服务 + Quartz.NET
服务基础 安装管理员打开cmd cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 InstallUtil.exe Path_WinSvc.exe 或者 ...
- eclipse开发scrapy爬虫工程,附爬虫临门级教程
写在前面 自学爬虫入门之后感觉应该将自己的学习过程整理一下,也为了留个纪念吧. scrapy环境的配置还请自行百度,其实也不难(仅针对windows系统,centos配置了两天,直到现在都没整明白) ...
- mariadb-server安装问题(Error: MariaDB-common conflicts with 1:mariadb-libs-5.5.60-1.el7_5.x86_64)
问题:今天在安装mariadb-server包时,提示错误,无法正确安装linux自带的mariadb包,提示错误很明确,是由于MariaDB-common包与mariadb-libs包冲突. 解决办 ...
- nginx屏蔽版本号
nginx的http段添加 server_tokens off; 在nginx.conf文件内如上增加server_tokens off;就隐藏了
- OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)
简介 Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同. 首先,uniform是全局的(Global).全局意味着uniform变量必须在每个着 ...