MyBatis映射文件深入_动态SQL之foreach
foreach标签一般用于IN()函数
我们往往在查询时还有一种需求:
就是当我们要查询操作的时候我们不知道到底会传输过来多少个查询条件, 比如可能是我们要查询某个数据表中id值为某个集合中的数据的时候, 这个时候随着集合的变化我们的查询出的数据就会随着集合的变化而变化, 这个时候我们就要使用到foreach标签(如下:)
映射文件中:
<select id = "findById" parameterType = "list" resultType = "user">
select * from user
<where>
<foreach collection = "list" open = "id in (" close = ")" item = "id" separator = ",">
#{id}
</foreach>
</where>
</select>
- foreach标签中的collection的值为list表示传入的是一个集合, 如果是一个数组, 那么就写为collection = “array”
- 我们从select标签中的parameterType属性值可以看出我们此时是传入了一个list集合
- foreach标签中的open的值表示以什么开始
- foreach标签中的close的值表示以什么结束
- foreach标签中的item就是在open和close值之间的变量, 就相当于Java中foreach循环中的临时变量
- 其实item的属性值就是一个临时变量, 就相当于一个别名, 所以其实真正的填充值值还是#{id}, 而此时的item属性值只是一个临时变量, 我们每次之后都是将填充值填充到了对应的临时变量中
- foreach 标签中的separation就是每个item之间的分隔符
最终呈现的结果就是:
select * from user where id in(id,id,id)
- 最终这三个临时变量id的值都会被#{id}每次的取值进行填充
- #{id}的取值就是在遍历list集合
测试:
public void test1() throws IOException{
//使用流的方式加载核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//使用SqlSessionFactory工厂构建器对象调用build()方法构建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//调用SqlSessionFactory工厂对象调用openSession()方法来构建一个
SqlSession sqlSession = sqlSessionFactory.openSession();
//使用SqlSession会话对象调用getMapper获取接口的动态代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//创建一个List集合, 模拟ids的数据, 也就是模拟一堆id值
List<Integer> ids = new ArrayList<>();
//使用动态代理对象调用其中的方法, 传入一个List集合进行查询
List<User> userList = mapper.findByIds(ids);
System.out.println(userList);
}
- 我们可以发现这种方式下我们日志中看到的sql语句中的IN()函数中的?占位符会根据传入的List< Integer>集合中的元素个数的变化而同步的变化
补充:
一个映射文件中可以有多个select等statement操作标签, 也就意味着一个mapper接口中可以定义多个抽象方法, 那么对应使用SqlSession会话对象调用getMapper()方法之后获得的动态代理对象中也就是实现了多个抽象方法的