昝沛珊 发表于 昨天 22:36

mybatis-plus的in,是传Array还是传List?仔细一看方法签名,瞬间秒懂

引子

先看个技术题吧。
下面两段代码,执行testFoo,结果分别是什么?(答案见文末)
@Test
public void testFoo() {
    foo(Arrays.asList(1, 2, 3));
}

void foo(Object... args) {
    System.out.println(args +"------"+ JSON.toJSONString(args));
}@Test
public void testFoo() {
    foo(Arrays.asList(1, 2, 3));
}

void foo(Object... args) {
    System.out.println(args +"------"+ JSON.toJSONString(args));
}void foo(List list){    System.out.println(list +"------"+ JSON.toJSONString(args));} 
一眼看出来结果的同学,恭喜你,本文内容可以略过。
 
下面是正文。
 
springboot项目通常配合mybatisplus来做数据CRUD。

我们在查询或更新数据的时候,有时要用到in来过滤数据。比如
SELECT * FROM emax_scbg_order WHERE order_no IN (1305679009380433922,1305405259472830465)

mybatisplus中关于in方法的使用,在传多个字段值的时候,我们经常搞不清是传Array呢还是ArrayList呢?
其实,细心的同学,看一下in方法的签名定义,就明白了。
mybatisplus中有4个in方法的重载。

所有Wrapper的超类是AbstractWrapper,AbstractWrapper实现了Func接口。in方法主要在Func接口中定义。

 
 下面是Func接口中in方法的4个重载:
//mybatis-plus-core-3.1.2.jar
package com.baomidou.mybatisplus.core.conditions.interfaces;

/**
* 查询条件封装
*
* @author hubin miemie HCL
* @since 2017-05-26
*/
@SuppressWarnings("unchecked")
public interface Func<Children, R> extends Serializable {
    /**
   * ignore
   */
    default Children in(R column, Collection<?> coll) {
      return in(true, column, coll);
    }
   
    /**
   * ignore
   */
    default Children in(R column, Object... values) {
      return in(true, column, values);
    }   

    /**
   * 字段 IN (v0, v1, ...)
   * <p>例: in("id", 1, 2, 3, 4, 5)</p>
   *
   * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
   *
   * @param condition 执行条件
   * @param column    字段
   * @param values    数据数组
   * @return children
   */
    default Children in(boolean condition, R column, Object... values) {
      return in(condition, column, Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
            .collect(toList()));
    }
   
    /**
   * 字段 IN (value.get(0), value.get(1), ...)
   * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
   *
   * <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
   *
   * @param condition 执行条件
   * @param column    字段
   * @param coll      数据集合
   * @return children
   */
    Children in(boolean condition, R column, Collection<?> coll);

}
单从方法签名以及清晰的javadoc注释,我们可以看到,in方法接收字段值的方式有两种,一种是Object...,一种是Collection。
■ Collection不用说了,是集合,比如List、Set、Queue等。
■ Object...是可变长参数(可变参数),可变长参数本质上就是一个数组,既可以接收一个或多个离散的值,也可以接收数组对象。
也就是说,in方法同时支持传入数组和集合。当我们入参是List时,调用的是重载的in(Collection),其他入参方式则是调用重载的in(Object...)。由此看来,调用mybatis-plus的in时,是传Array还是传List?就见分晓了。
现在,我们来做一个假设:假设这些in重载方法里没有in(Collection),只有in(Object...),那么,我们应用程序在调用的时候,当需要in的参数值是一个集合时,如果我们把集合直接传给in(Object...),那就是bug。因为在可变长参数里,集合对象只是可变长参数的其中一个元素(不是多个)。也就是说,在这种假设下,程序生成的SQL会是 SELECT * FROM table1 WHERE state IN ('') ,我们的程序为规避这个bug,就要先把集合转换为数组再调用in(Object...)。显然,这样会给我们的开发带来额外的工作,更糟糕的是,这样的bug很难彻底规避。
mybatis-plus框架的研发团队显然意识到了这个“假设”,故而增加了重载的in(Collection),毋庸置疑是非常优秀的设计。
下面详细列举使用in的姿势。
 
使用in的姿势



来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: mybatis-plus的in,是传Array还是传List?仔细一看方法签名,瞬间秒懂