mybatis 参数为集合时的处理

mybatis 集合包装

版本:

名称 版本
java 1.8.0_102
mybatis 3.4.6

性价比分析:

价值 ★☆
实用 ★★★☆

例子

Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aya.mapper.BlogMapper">

    <select id="selectBlogInId" resultType="com.aya.mapper.Blog" >
        select * from blog where id in
        <foreach item="id" collection="array" separator="," open="(" close=")">
            #{id}
        </foreach>
    </select>

</mapper>

测试代码

    @Test
    public void testReadWrapCollection() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            Object [] params = {"2","3"};
            List<Object> objects = sqlSession.selectList("selectBlogInId",params);
            System.out.println(objects);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

控制台输出:

[Blog{id=2, title='title2', content='content2'}, Blog{id=3, title='title3', content='content3'}]

疑问

  1. foreach 遍历的集合名称为什么是 array ?
  2. 集合作为参数时,遍历的名称是什么

分析

葛二蛋: 二狗啊,回来啦,走啊,去村东头玩去

二狗: 好啊好啊,不过在去之前,我们一起先分析一下这个例子吧!

葛二蛋: 啊,看起来一头雾水嘛, 为什么名字是array呢

二狗: 不明白就去源码里面看看不就知道了

葛二蛋: 恩,可是从哪里入手呢?

二狗: 笨,这个都不知道, 既然是查询,你就去查询里面看咯,我们跟着 selectList 顺藤摸瓜肯定能找到原因的

扫描二维码关注公众号,回复: 2286069 查看本文章

葛二蛋: 那我们开始吧

  @Override
  public <E> List<E> selectList(String statement) {
    return this.selectList(statement, null);
  }

  @Override
  public <E> List<E> selectList(String statement, Object parameter) {
    return this.selectList(statement, parameter, RowBounds.DEFAULT);
  }

  @Override
  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

葛二蛋: 我找到包装集合的地方了,在 executor.query 之前,对集合进行包装, 二狗,你说对不对啊

wrapCollection(parameter)

二狗: dei,dei,dei,港得dei

葛二蛋: 那就在跟进去一层看看

  private Object wrapCollection(final Object object) {
    if (object instanceof Collection) {
      StrictMap<Object> map = new StrictMap<Object>();
      map.put("collection", object);
      if (object instanceof List) {
        map.put("list", object);
      }
      return map;
    } else if (object != null && object.getClass().isArray()) {
      StrictMap<Object> map = new StrictMap<Object>();
      map.put("array", object);
      return map;
    }
    return object;
  }

葛二蛋: 就这么简单啊,我还没做好害怕的准备就已经结束了

二狗: 没错,就是这么简单,那我们一起总结一下吧

葛二蛋: 这还要一起总结? 我一个人就行
1. 数组: array
2. List的实现类: list
3. Collection 的实现类 collection

二狗: 文字总结还是太绕了,我们来画个图
包装集合关键字图

二狗: 现在明白了遍历的时候为什么是array了吧

葛二蛋: 恩,我明白了,我还以为可以随便改呢,这下就清楚了

总结

  1. 因为参数是数组类型,所以 foreach 的时候,集合名称是 array
  2. 包装的集合的关键字总共有三种: array,list,collection

猜你喜欢

转载自blog.csdn.net/mz4138/article/details/81019065