为什么Mybatis在查询单个字段时却返回了整个对象?
最近基于mybatis,新建一个父类接口,想快速实现所有表查询最后更新时间的功能
public interface MyBaseMapper<T> { @SelectProvider(
type = LastUpdateTimeProvider.class,
method = "getLastUpdateTime"
)
LocalDateTime getLastUpdateTime(Class<T> clazz);
}
@UtilityClasspublic 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
,不得其解。
我做了以下尝试:
去掉了
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
- 去掉了自定义的一些
Interceptor
,排除干扰; debug追溯
Mybatis
的源码;- 首先追踪到
org.mybatis:mybatis:3.4.6
这个包中的org.apache.ibatis.binding.MapperMethod
的第83行result = sqlSession.selectOne(command.getName(), param);
- 一路debug,直到
org.apache.ibatis.session.Configuration
的第721行return mappedStatements.get(id);
- 这时候就发现,这个
mappedStatements
对象中,已经缓存好了我这个查询id,我在IDEA的watches中查看结果集,就发现mappedStatements.get("com.abc.def.XxxMapper.getLastUpdateTime")
的resultMaps
有两个值,第一个值为Xxx
对象,第二个值为LocalDateTime
,对于这个mappedStatements
如何生成的,我暂时还不太了解,在提出这个问题以后,我再继续了解一下,看能否从这里解决问题; - 后面的代码就没啥了,就直接根据这个
resultMaps
生成结果,然后再返回
- 首先追踪到
以上是 为什么Mybatis在查询单个字段时却返回了整个对象? 的全部内容, 来源链接: utcz.com/p/944123.html