AbstractLambdaWrapper 最终会调用 columnToString(SFunction<T, ?> column, boolean onlyColumn)
调用 getColumn(LambdaUtils.resolve(column), onlyColumn)
核心逻辑
Class<?> aClass = lambda.getInstantiatedType();
if (!initColumnMap) {
columnMap = LambdaUtils.getColumnMap(aClass);
initColumnMap = true;
}
Assert.notNull(columnMap, "can not find lambda cache for this entity [%s]", aClass.getName());
此时 lambda 为 SFunction -> IndexQuoteCommon::getIfValid
aClass 为 IndexQuoteCommon(公共实体抽象类或者接口,因为你要抽取公共逻辑是建立在公共的字段上的)
进到 LambdaUtils.getColumnMap(aClass) 方法
return COLUMN_CACHE_MAP.computeIfAbsent(clazz.getName(), key -> {
TableInfo info = TableInfoHelper.getTableInfo(clazz);
return info == null ? null : createColumnCacheMap(info);
});
COLUMN_CACHE_MAP 是被标记了 @TableName("xxx") 才会被缓存的表字段,而我们的抽象类IndexQuoteCommon 实际上是不在这个数据字典类的
最终报错:can not find lambda cache for this entity [%s]
或者:com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: 该方法仅能传入 lambda 表达式产生的合成类
注:TableInfo 是 mybatis 的对表描述的类
有没方式解决呢?如果只从 lambda 角度去实现,可能不太现实,因为抽象类必须要被加载到COLUMN_CACHE_MAP。
我们可以使用普通字符串 query 方式,直接绕过 columnToString 方式