找回密码
 立即注册
首页 业界区 业界 mybatis-plus的in,是传Array还是传List?仔细一看方法 ...

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

昝沛珊 前天 22:36
引子

先看个技术题吧。
下面两段代码,执行testFoo,结果分别是什么?(答案见文末)
  1. @Test
  2. public void testFoo() {
  3.     foo(Arrays.asList(1, 2, 3));
  4. }
  5. void foo(Object... args) {
  6.     System.out.println(args +"------"+ JSON.toJSONString(args));
  7. }
复制代码
  1. @Test
  2. public void testFoo() {
  3.     foo(Arrays.asList(1, 2, 3));
  4. }
  5. void foo(Object... args) {
  6.     System.out.println(args +"------"+ JSON.toJSONString(args));
  7. }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接口中定义。
1.png

 
 下面是Func接口中in方法的4个重载:
  1. //mybatis-plus-core-3.1.2.jar
  2. package com.baomidou.mybatisplus.core.conditions.interfaces;
  3. /**
  4. * 查询条件封装
  5. *
  6. * @author hubin miemie HCL
  7. * @since 2017-05-26
  8. */
  9. @SuppressWarnings("unchecked")
  10. public interface Func<Children, R> extends Serializable {
  11.     /**
  12.      * ignore
  13.      */
  14.     default Children in(R column, Collection<?> coll) {
  15.         return in(true, column, coll);
  16.     }
  17.    
  18.     /**
  19.      * ignore
  20.      */
  21.     default Children in(R column, Object... values) {
  22.         return in(true, column, values);
  23.     }   
  24.     /**
  25.      * 字段 IN (v0, v1, ...)
  26.      * <p>例: in("id", 1, 2, 3, 4, 5)</p>
  27.      *
  28.      * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
  29.      *
  30.      * @param condition 执行条件
  31.      * @param column    字段
  32.      * @param values    数据数组
  33.      * @return children
  34.      */
  35.     default Children in(boolean condition, R column, Object... values) {
  36.         return in(condition, column, Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
  37.             .collect(toList()));
  38.     }
  39.    
  40.     /**
  41.      * 字段 IN (value.get(0), value.get(1), ...)
  42.      * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
  43.      *
  44.      * <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
  45.      *
  46.      * @param condition 执行条件
  47.      * @param column    字段
  48.      * @param coll      数据集合
  49.      * @return children
  50.      */
  51.     Children in(boolean condition, R column, Collection<?> coll);
  52. }
复制代码
单从方法签名以及清晰的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 ('[SUCCESS,FAIL]') ,我们的程序为规避这个bug,就要先把集合转换为数组再调用in(Object...)。显然,这样会给我们的开发带来额外的工作,更糟糕的是,这样的bug很难彻底规避。
mybatis-plus框架的研发团队显然意识到了这个“假设”,故而增加了重载的in(Collection),毋庸置疑是非常优秀的设计。
下面详细列举使用in的姿势。
 
使用in的姿势



来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册