为什么Mybatis在查询单个字段时却返回了整个对象?

最近基于mybatis,新建一个父类接口,想快速实现所有表查询最后更新时间的功能

public interface MyBaseMapper<T> {

@SelectProvider(

type = LastUpdateTimeProvider.class,

method = "getLastUpdateTime"

)

LocalDateTime getLastUpdateTime(Class<T> clazz);

}

@UtilityClass

public class LastUpdateTimeProvider {

public String getLastUpdateTime(Class<? extends BaseEntity> clazz) {

return "select max(update_time) from " + getTableName(clazz);

}

public String getTableName(Class<?> modelClass) {

Table table = modelClass.getAnnotation(Table.class);

if (table != null) {

return table.name();

}

return modelClass.getName();

}

}

最后生成的SQL类似于:

select max(update_time) from t_xxx

以获取最后一次数据更新的时间戳。直接查询数据库,所有表的查询结果都不为空。

但通过Mybatis执行的时候,总是返回null,不得其解。

我做了以下尝试:

  1. 去掉了MyBaseMapper,直接在子类中使xml的方式完成查询,并且修改了sql

     <select id="getLastUpdateTime" resultType="java.time.LocalDateTime">

    select update_time from t_xxx order by update_time limit 1;

    </select>

    这样查询Mybatis会返回对象xxx,而不是LocalDateTime,错误如下:

    java.lang.ClassCastException: com.abc.def.Xxx cannot be cast to java.time.LocalDateTime
  2. 去掉了自定义的一些Interceptor,排除干扰;
  3. debug追溯Mybatis的源码;

    1. 首先追踪到org.mybatis:mybatis:3.4.6这个包中的org.apache.ibatis.binding.MapperMethod的第83行result = sqlSession.selectOne(command.getName(), param);
    2. 一路debug,直到org.apache.ibatis.session.Configuration的第721行return mappedStatements.get(id);
    3. 这时候就发现,这个mappedStatements对象中,已经缓存好了我这个查询id,我在IDEA的watches中查看结果集,就发现mappedStatements.get("com.abc.def.XxxMapper.getLastUpdateTime")resultMaps有两个值,第一个值为Xxx对象,第二个值为LocalDateTime,对于这个mappedStatements如何生成的,我暂时还不太了解,在提出这个问题以后,我再继续了解一下,看能否从这里解决问题;
    4. 后面的代码就没啥了,就直接根据这个resultMaps生成结果,然后再返回

以上是 为什么Mybatis在查询单个字段时却返回了整个对象? 的全部内容, 来源链接: utcz.com/p/944123.html

回到顶部