- 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,T>泛型,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

/**
 * 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);
    }

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

- 也就是说,像本例多继承的情况下,由于父类BasePurchaseOrderService没有泛型参数
- 对于currentModelClass方法,最终获取了
java.lang.Object- 最终报错了
public class PurchaseOrderServiceImpl extends BasePurchaseOrderService implements PurchaseOrderService {}
- 所以解决方法就很容易理解,给继承的父类方法加上对应的<M,T>泛型参数即可
- 或者重写对应的方法,让其返回正确的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最终获执行报错


![[LeetBook]【学习日记】有效数字——状态机](https://img-blog.csdnimg.cn/direct/20d29e0d3a754a9e910202f39a704469.png)









![[项目设计] 从零实现的高并发内存池(四)](https://img-blog.csdnimg.cn/c446ebae288e480d84f5d14d494c88bb.gif)






