Mybatis框架的动态SQL可以方便的拼接SQL语句,而其foreach标签可用于处理集合类型数据。本文介绍如何使用foreach标签遍历传入的集合(List, Array, Map)
概述
foreach标签,可以实现遍历集合类型(List, Array, Map)数据。该标签包含如下属性:
- collection: [必选参数] 需要进行遍历对象对应的键:List对象默认使用list作为键,Array对象默认使用array作为键,Map对象没有默认的键(需要使用@Param注解完成Map对象的绑定,下文将详述),当集合(List, Array, Map)对象为所传实参POJO的一个属性时,集合对象使用属性名作为键
- item: [必选参数] 用于表示每次遍历时的集合中的元素名称,可以通过点操作符访问元素属性。在Map中,表示value
- index: [可选参数] List、Array集合中表示元素序号。Map集合中表示key
- separator: [可选参数] 两次遍历结果之间所添加的分隔符
- open: [可选参数] 添加在最终遍历结果之前的符号
- close: [可选参数] 添加在最终遍历结果之后的符号
先给出本文代码可能用到的相关POJO类(属性名和数据表的字段均对应)
1 | public class Student { |
1 | public class UserVo { |
参数为集合
传入的参数为集合类型时,collection按上文所述配置相应的键即可
List
构造一个Student的List集合对象后传入service
1 | List<Student> list = new LinkedList<>(); |
Mapper接口如下,service将调用该接口方法
1 |
|
传入参数为集合时,映射文件的sql标签parameterType属性可省略。这里由于是List集合,故collection使用默认键list,而item属性可以任意指定,用来标识每次遍历的元素对象名称,这里记为node,则表示每次遍历的元素的属性时,可以使用点操作符,如node.address,node.sex所示
1 | <select id="findAddByName3" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出List中元素的属性数据
Array
构造一个Student的Array集合对象后传入service
1 | Student[] array = new Student[21]; |
Mapper接口如下,service将调用该接口方法
1 |
|
传入参数为集合时,映射文件的sql标签parameterType属性可省略。这里由于是Array,故collection使用默认键array,而item属性可以任意指定,用来标识每次遍历的元素对象名称,这里记为node,则表示每次遍历的元素的属性时,可以使用点操作符,如node.address,node.sex所示。需要注意的是,foreach将遍历数组的所有元素,所以每次取该元素的属性前,需要先对该元素对象进行判空(如下所示)
1 | <select id="findAddByName4" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出数组中元素的属性数据
Map
构造一个Student的Map集合对象后传入service
1 | Map<String,String> map = new HashMap<>(); |
Mapper接口如下,service将调用该接口方法,需要注意的是,Map集合在foreach由于没有默认键可用,故需要使用 @Param 注解手动指定一个标识,后面将在foreach中将其作为键使用。该标识任意指定即可,这里使用”stuMap”
1 | interface StudentMapper { |
传入参数为集合时,映射文件的sql标签parameterType属性可省略。由于是Map集合,collection无默认键,故配置其为对应的接口方法中的形参前的@Param注解中的标识(此处即为”stuMap”)。由于是Map集合,index、item属性分别表示为该Map集合中的key、value,故可以分别用${k},#{v}来获取该Map集合中的key、value
1 | <select id="findAddByName2" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出Map集合中key-value数据
参数为包含集合属性的POJO
传入的参数为一个POJO,其属性中有集合类型时,collection直接配置为相应集合中的属性名即可
POJO 属性为 List
构造下列一个UserVo对象同时设置一个List集合属性,传入service
1 | UserVo userVo = new UserVo(); |
Mapper接口如下,service将调用该接口方法
1 | public interface StudentMapper { |
传入参数为UserVo类型,故映射文件的sql标签parameterType属性配置为UserVo。该POJO的stuList属性为List集合类型,在遍历该属性的List集合时,collection配置为该属性名stuList即可。而item属性可以任意指定,用来标识每次遍历的元素对象名称,这里记为node,则表示每次遍历的元素的属性时,可以使用点操作符,如node.address,node.sex所示
1 | <select id="findAddByName6" parameterType="com.aaron.springbootdemo.pojo.UserVo" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出List中元素的属性数据
POJO 属性为 Array
构造下列一个UserVo对象同时设置一个Array属性,传入service
1 | UserVo userVo = new UserVo(); |
Mapper接口如下,service将调用该接口方法
1 | public interface StudentMapper { |
传入参数为UserVo类型,故映射文件的sql标签parameterType属性配置为UserVo。该POJO的stuArray属性为Array类型,在遍历该属性的Array时,collection配置为该属性名stuArray即可。而item属性可以任意指定,用来标识每次遍历的元素对象名称,这里记为node,则表示每次遍历的元素的属性时,可以使用点操作符,如node.address,node.sex所示。需要注意的是,foreach将遍历数组的所有元素,所以每次取该元素的属性前,需要先对该元素对象进行判空(如下所示)
1 | <select id="findAddByName5" parameterType="com.aaron.springbootdemo.pojo.UserVo" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出数组中元素的属性数据
POJO 属性为 Map
构造下列一个UserVo对象同时设置一个Map属性,传入service
1 | UserVo userVo = new UserVo(); |
Mapper接口如下,service将调用该接口方法
1 | public interface StudentMapper { |
传入参数为UserVo类型,故映射文件的sql标签parameterType属性配置为UserVo。该POJO的stuMap属性为Map类型,在遍历该属性的Map时,collection配置为该属性名stuMap即可。由于是Map集合,index、item属性分别表示为该Map集合中的key、value,故可以分别用${k},#{v}来获取该Map集合中的key、value
1 | <select id="findAddByName7" parameterType="com.aaron.springbootdemo.pojo.UserVo" resultMap="studentResultMap"> |
下图即为上述代码执行后的结果,可以看出正确遍历拼接出Map集合中key-value数据