关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法

        • 0. 接口结构:
        • 1. 方法报错:
        • 2. 解决方法:
        • 3. 原因分析:

0. 接口结构:

【接口】:

public interface PurchaseOrderService extends IService<PurchaseOrder> {}

【接口实现类】:

public class PurchaseOrderServiceImpl extends BasePurchaseOrderService implements PurchaseOrderService {}

【实现类基类】

abstract class BasePurchaseOrderService extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> {}

结构:不同类型的订单会有不同是实现类,对于一些公共的操作,会在基类中实现

1. 方法报错:
  • 当执行Mybatis-Plus的ServiceImpl一些方法,比如updateBatchById、saveBatch等
  • 便会报错:Not Found TableInfoCache
2. 解决方法:
  • 修改接口结构,基类使用泛型,M:Mapper类;T:对应的Model类

【接口实现类】:

public class PurchaseOrderServiceImpl extends BasePurchaseOrderService<PurchaseOrderMapper, PurchaseOrder> implements PurchaseOrderService {}

【实现类基类】

abstract class BasePurchaseOrderService<M extends BaseMapper<T>, T> extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> {}

  • 此外,还有一种解决方法,参考连接:https://github.com/baomidou/mybatis-plus/issues/578
  • 就是重写ServiceImpl的currentModelClass方法和currentMapperClass方法
abstract class BasePurchaseOrderService extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements BaseService<PurchaseOrder> {
	
	@Override
    protected Class<PurchaseOrder> currentModelClass() {
        return (Class<PurchaseOrder>) GenericTypeResolver.resolveTypeArgument(getClass(), BaseService.class);
    }

	// currentMapperClass的重写方法不知道怎么实现... ... 
}

public interface BaseService<T> extends IService<T>{}



3. 原因分析:
  • updateBatchById来,调用链路:
  • executeBatch ➡ sqlSessionFactory ➡ currentSessionFactory ➡ getTableInfo

关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法_第1张图片


/**
 * IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
 *
 * @author hubin
 * @since 2018-06-23
 */
@SuppressWarnings("unchecked")
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {

    protected Class<T> entityClass = currentModelClass();

    protected Class<T> mapperClass = currentMapperClass();

    /**
     * 执行批量操作
     *
     * @param consumer consumer
     * @since 3.3.0
     * @deprecated 3.3.1 后面我打算移除掉 {@link #executeBatch(Collection, int, BiConsumer)} }.
     */
    @Deprecated
    protected boolean executeBatch(Consumer<SqlSession> consumer) {
        return SqlHelper.executeBatch(this.entityClass, this.log, consumer);
    }

关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法_第2张图片
关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法_第3张图片

  • 显然:getTableInfo获取为null才报的错,从报错也知道,此时的class 为java.lang.Object
  • 显然获取的class不对,而class就是ServiceImpl的entityClass
  • 默认下,entityClass取的父类的第2个泛型参数,mapperClass取的父类的第1个泛型参数

关于Mybatis-Plus报错 Not Found TableInfoCache 解决办法_第4张图片

  • 也就是说,像本例多继承的情况下,由于父类BasePurchaseOrderService没有泛型参数
  • 对于currentModelClass方法,最终获取了java.lang.Object
  • 最终报错了
public class PurchaseOrderServiceImpl extends BasePurchaseOrderService implements PurchaseOrderService {}
  • 所以解决方法就很容易理解,给继承的父类方法加上对应的泛型参数即可
  • 或者重写对应的方法,让其返回正确的entityClass,mapperClass
  • 正常没有多继承的情况,是不是就没问题,其父类ServiceImpl有泛型参数
  • mapperClass 为PurchaseOrderMapper;entityClass为PurchaseOrder
public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements PurchaseOrderService {}

  • 另外提一下,mapperClass用于获取sqlStatement
  • String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
  • 最终:sqlStatement = mapper.getName() + StringPool.DOT + sqlMethod.getMethod();
  • 而sqlStatement用于获取最终的语句执行,不正确的sqlStatement最终获执行报错

你可能感兴趣的:(SQL,mybatis,MP,tableInfo,java,mybatis-plus)