解决Mybatis使用map封装结果,字段值为NULL时默认不封装问题

解决方法

Mybatis配置类中获取SqlSessionFactoryBean中配置:


        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setCallSettersOnNulls(true);
        configuration.setReturnInstanceForEmptyRow(true);
        gpSqlSessionFactory.setConfiguration(configuration);

很多网上教程只配置了configuration.setCallSettersOnNulls(true),没有configuration.setReturnInstanceForEmptyRow(true);会导致筛选字段都为NULL时会封装不上的问题,所以一定要两个都要配置。

源码分析

在org.apache.ibatis.executor.resultset.DefaultResultSetHandler类中方法:

  private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
    final ResultLoaderMap lazyLoader = new ResultLoaderMap();
    Object rowValue = createResultObject(rsw, resultMap, lazyLoader, null);
    if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
      final MetaObject metaObject = configuration.newMetaObject(rowValue);
      boolean foundValues = this.useConstructorMappings;
      if (shouldApplyAutomaticMappings(resultMap, false)) {
        foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
      }
      foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
      foundValues = lazyLoader.size() > 0 || foundValues;
      //这里会拿上面的配置configuration.setReturnInstanceForEmptyRow(true);但foundValues为false也会封装结果
      rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
    }
    return rowValue;
  }
    private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
    List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
    boolean foundValues = false;
    if (!autoMapping.isEmpty()) {
      for (UnMappedColumnAutoMapping mapping : autoMapping) {
        final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
        if (value != null) {
          foundValues = true;
        }
        //这里会拿我们上面设置configuration.setCallSettersOnNulls(true);这个配置当foundValues为false也会将值保存
        if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) {
          // gcode issue #377, call setter on nulls (value is not 'found')
          metaObject.setValue(mapping.property, value);
        }
      }
    }
    return foundValues;
  }

以上就是我遇到查询为NULL时,Mybatis不封装的解决方法,如还有其他方式还请各网友留言,蟹蟹!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设你使用的是mybatis-plus框架,同也已经实现了查询两条数据并将这两条数据中的`department`字段相互替换的逻辑,那么接下来你可以使用mybatis-plus提供的`UpdateWrapper`类来更新表数据。 首先,你需要将查询出来的两条记录中的`department`字段相互替换,然后将这两条记录的`id`值保存到一个列表中,如下所示: ```java List<Map<String,Object>> resultList = ...; String department1 = null; String department2 = null; List<Long> idList = new ArrayList<>(); for (Map<String,Object> map : resultList) { if (map.get("id").equals(id1)) { department1 = (String)map.get("department"); idList.add(id1); } else if (map.get("id").equals(id2)) { department2 = (String)map.get("department"); idList.add(id2); } } ``` 接下来,你可以使用`UpdateWrapper`类来构造更新条件,并调用`update`方法来更新表数据。具体代码如下: ```java UpdateWrapper wrapper = new UpdateWrapper(); wrapper.in("id", idList); wrapper.set("department", department1, SqlKeyword.EQUALS, department2); employeeMapper.update(null, wrapper); ``` 上面的代码中,我们先构造了一个`UpdateWrapper`对象,其中使用了`in`方法来设置更新条件,只更新`id`值在`idList`中的记录。然后,我们使用`set`方法来设置需要更新的字段和对应的值,注意使用了`SqlKeyword.EQUALS`来表示对应的值需要相互替换。最后,我们调用了`update`方法来执行更新操作,并将`UpdateWrapper`对象作为第一个参数传递给`update`方法,表示更新条件。`null`表示不设置更新的实体对象。 需要注意的是,上面的代码中,`employeeMapper`是一个mybatis-plus生成的Mapper类,你需要根据自己的实际情况来替换。同,为了保证代码的可读性和可维护性,你可能需要将上面的代码封装成一个Service方法来使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值