引子
先看个技术题吧。
下面两段代码,执行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 ('[SUCCESS,FAIL]') ,我们的程序为规避这个bug,就要先把集合转换为数组再调用in(Object...)。显然,这样会给我们的开发带来额外的工作,更糟糕的是,这样的bug很难彻底规避。
mybatis-plus框架的研发团队显然意识到了这个“假设”,故而增加了重载的in(Collection),毋庸置疑是非常优秀的设计。
下面详细列举使用in的姿势。
使用in的姿势
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |