mybatis-plus集合判空避坑

4 篇文章 0 订阅
3 篇文章 0 订阅

昨天发现一个鬼畜问题,测试环境和生产的配置互换后,测试后把环境切换回测试就一直报错,原因是用户表中生的一个用户生成了两个openId,getOne后报错,于是做出了一些改变:

QueryWrapper<MiniproUser> wrapper = new QueryWrapper<MiniproUser>().eq("openid",
					loginResult.getOpenid());
MiniproUser user = this.list(wrapper) == null?null:this.list(wrapper).get(0);

把原来的getOne()改为了list,有数据取第一条,结果偏偏集合判空这里出了,如果用户不存在,走到这行代码直接抛异常。这里对OpenId重新设置下,模拟新用户注册的情况:

 

 结果发现成勋直接跳到了catch代码块并抛出:java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

有说法是:

实体类使用了@Builder注解,则无法使用无参构造函数,最终导致mybatis在创建实体时报错

在实体类加上@NoArgsConstructor和@AllArgsConstructor即可使用无参构造函数(来源:Mybatis查询报IndexOutOfBoundsException - 博客 - 编程圈

但是我确实使用了@Builder,但是也已经添加了@NoArgsConstructor和@AllArgsConstructor:

微微一笑发现问题并没有那么简单,既然直接判空集合不行,用工具类试试,然后调试进入看一下:

于是进行改造如下:

MiniproUser user = ObjectUtils.isEmpty(this.list(wrapper))?null:this.list(wrapper).get(0);

进入isEmpty()调试发现:

/**
	 * Determine whether the given object is empty.
	 * <p>This method supports the following object types.
	 * <ul>
	 * <li>{@code Optional}: considered empty if {@link Optional#empty()}</li>
	 * <li>{@code Array}: considered empty if its length is zero</li>
	 * <li>{@link CharSequence}: considered empty if its length is zero</li>
	 * <li>{@link Collection}: delegates to {@link Collection#isEmpty()}</li>
	 * <li>{@link Map}: delegates to {@link Map#isEmpty()}</li>
	 * </ul>
	 * <p>If the given object is non-null and not one of the aforementioned
	 * supported types, this method returns {@code false}.
	 * @param obj the object to check
	 * @return {@code true} if the object is {@code null} or <em>empty</em>
	 * @since 4.2
	 * @see Optional#isPresent()
	 * @see ObjectUtils#isEmpty(Object[])
	 * @see StringUtils#hasLength(CharSequence)
	 * @see StringUtils#isEmpty(Object)
	 * @see CollectionUtils#isEmpty(java.util.Collection)
	 * @see CollectionUtils#isEmpty(java.util.Map)
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(@Nullable Object obj) {
		if (obj == null) {
			return true;
		}

		if (obj instanceof Optional) {
			return !((Optional) obj).isPresent();
		}
		if (obj instanceof CharSequence) {
			return ((CharSequence) obj).length() == 0;
		}
		if (obj.getClass().isArray()) {
			return Array.getLength(obj) == 0;
		}
		if (obj instanceof Collection) {
			return ((Collection) obj).isEmpty();
		}
		if (obj instanceof Map) {
			return ((Map) obj).isEmpty();
		}

		// else
		return false;
	}

第一个if判断obj竟然不是null,查看堆栈信息,发现里边是一个LinkedList,而且内部还有Map,存放有框架和mybatis的一些东西,猜想是一个返回数据集的附加信息,但是没有真正需要的数据在里边,因此,为了保险起见,改成

ObjectUtils.isEmpty(this.list(wrapper))
或者
this.list(wrapper).size == 0

经过测试两者都可以。

总结:在使用框架或者封装第三方的工具时,对于一些常见的集合操作或者判断操作,还是谨慎选择,因为经过层层封装后的对象,你不知道里边带了究竟有多少其他的东西,很可能会给出错误的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值