为了让我的SqlUtil用起来更香,我准备将SqlHelper中的saveOrUpdateBatch方法的参数从Class> mapper换成mapper的实体类,再通过mapper.getClass()的方式获取其真实类。
如果是批量插入会报:
Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.sun.proxy.$Proxy129.insert
如果是执行批量更新则会报:
Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.sun.proxy.$Proxy129.updateById

代码如下:
- public static
extends BaseEntity, R extends BaseMapper> void saveBatch(Class mapperClass, List entityList, Long userId) { - saveBatch(mapperClass, entityList, userId, 10000);
- }
-
- public static
extends BaseEntity, R extends BaseMapper> void saveBatch(R mapper, List entityList, Long userId) { - saveBatch(mapper.getClass(), entityList, userId, 10000);
- }
-
- public static
extends BaseEntity, R extends BaseMapper> void saveBatch(Class mapperClass, List entityList, Long userId, int batchSize) { - if (entityList.size() == 0) {
- return;
- }
- T t = entityList.get(0);
- Class
entityClass = (Class) t.getClass(); - SqlHelper.saveOrUpdateBatch(entityClass, mapperClass, log, entityList, batchSize, (sqlSession, entity) -> {
- // INFO: DCTANT: 2021/12/27 insert判断,返回true则是走insert代码,返回false则会走后面的update代码
- if (entity == null) {
- return false;
- }
- Long id = entity.getId();
- if (id == null) {
- // INFO: DCTANT: 2021/12/27 insert前加一些自己必要的业务逻辑,如setCreateTime、setDel、setVersion等等
- insertNecessaryField(entity, userId);
- return true;
- } else {
- // INFO: DCTANT: 2021/12/27 去执行update的代码
- return false;
- }
- }, (sqlSession, entity) -> {
- // INFO: DCTANT: 2021/12/27 判断为update,然后执行必要操作
- if (entity == null) {
- return;
- }
- // INFO: DCTANT: 2021/12/27 update前加一些自己的业务逻辑,如setUpdateTime等等
- updateNecessaryField(entity, userId);
- MapperMethod.ParamMap
param = new MapperMethod.ParamMap<>(); - // INFO: DCTANT: 2022/8/22 参数需要为Constants.ENTITY,也就是里面的et,否则会报et这个参数无法找到
- param.put(Constants.ENTITY, entity);
- String sqlStatement = SqlHelper.getSqlStatement(mapperClass, SqlMethod.UPDATE_BY_ID);
- sqlSession.update(sqlStatement, param);
- });
- }
这个问题一开始报的让人摸不着头脑,若不是开了上帝视角,从前言中已经知道大概的问题原由,真是让人一头雾水,proxy类是哪来的,insert和updateById方法这两个方法在mapper中本来就有,凭什么会找不到!
这里一共三种写法,其中2、3是等价的

第一种写法打断点可得知拿到的就是Mapper它自己本身的类

这种写法能够反射获取其中的insert和updateById方法。
而第二、三种方法打断点获得的类是

实际是Java的代理类,Proxy类,这里面哪会存在insert和updateById方法,这就是报错的原因。所以方法不能胡乱抽取,这种就属于得不偿失,且无解。只能将本身的Class传入才能不报错,删除刚才的saveBatch(Class
如果大家有什么其他解法可以指出,本人虚心接受。