diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java index b3e9e523..33c9619a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java @@ -36,6 +36,8 @@ public class ClassUtil { // javassist , "javassist.util.proxy.ProxyObject" , "org.apache.ibatis.javassist.util.proxy.ProxyObject"); + private static final String ENHANCER_BY = "$$EnhancerBy"; + private static final String JAVASSIST_BY = "_$$_"; public static boolean isProxy(Class clazz) { for (Class cls : clazz.getInterfaces()) { @@ -47,12 +49,9 @@ public class ClassUtil { return Proxy.isProxyClass(clazz); } - private static final String ENHANCER_BY = "$$EnhancerBy"; - private static final String JAVASSIST_BY = "_$$_"; - public static Class getUsefulClass(Class clazz) { if (isProxy(clazz)) { - return (Class) clazz.getSuperclass(); + return getJdkProxySuperClass(clazz); } //ControllerTest$ServiceTest$$EnhancerByGuice$$40471411#hello -------> Guice @@ -235,4 +234,9 @@ public class ClassUtil { doGetMethods(cl.getSuperclass(), methods, predicate); } + private static Class getJdkProxySuperClass(Class clazz) { + final Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), clazz.getInterfaces()); + return (Class) proxyClass.getInterfaces()[0]; + } + } diff --git a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/service/IService.java b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/service/IService.java index b33e6705..224d34f4 100644 --- a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/service/IService.java +++ b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/service/IService.java @@ -19,6 +19,9 @@ import com.mybatisflex.core.BaseMapper; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryCondition; import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.Db; +import com.mybatisflex.core.row.RowMapper; +import com.mybatisflex.core.util.ClassUtil; import com.mybatisflex.core.util.CollectionUtil; import com.mybatisflex.core.util.SqlUtil; import org.springframework.transaction.annotation.Transactional; @@ -37,6 +40,8 @@ import java.util.*; @SuppressWarnings("unused") public interface IService { + // ===== 保存(增)操作 ===== + /** * 获取对应实体类(Entity)的基础映射类(BaseMapper)。 * @@ -44,8 +49,6 @@ public interface IService { */ BaseMapper getMapper(); - // ===== 保存(增)操作 ===== - /** * 保存实体类对象数据。 * @@ -80,6 +83,8 @@ public interface IService { return SqlUtil.toBool(getMapper().insertBatch(new ArrayList<>(entities))); } + // ===== 删除(删)操作 ===== + /** * 批量保存实体类对象数据。 * @@ -92,8 +97,6 @@ public interface IService { return SqlUtil.toBool(getMapper().insertBatch(new ArrayList<>(entities), size)); } - // ===== 删除(删)操作 ===== - /** * 根据查询条件删除数据。 * @@ -138,6 +141,8 @@ public interface IService { return SqlUtil.toBool(getMapper().deleteBatchByIds(ids)); } + // ===== 更新(改)操作 ===== + /** * 根据 {@link Map} 构建查询条件删除数据。 * @@ -148,8 +153,6 @@ public interface IService { return SqlUtil.toBool(getMapper().deleteByMap(query)); } - // ===== 更新(改)操作 ===== - /** * 根据查询条件更新数据。 * @@ -172,6 +175,34 @@ public interface IService { return SqlUtil.toBool(getMapper().updateByCondition(entity, condition)); } + /** + * 根据 id 批量更新数据 + * + * @param entities 实体类对象集合 + * @return boolean {@code true} 更新成功,{@code false} 更新失败。 + */ + default boolean updateBatch(Collection entities) { + return updateBatch(entities, RowMapper.DEFAULT_BATCH_SIZE); + } + + /** + * 根据 id 批量更新数据 + * + * @param entities 实体类对象集合 + * @param batchSize 每批次更新数量 + * @return boolean {@code true} 更新成功,{@code false} 更新失败。 + */ + @SuppressWarnings("unchecked") + default boolean updateBatch(Collection entities, int batchSize) { + return Db.tx(() -> { + final List entityList = CollectionUtil.toList(entities); + + // BaseMapper 是经过 Mybatis 动态代理处理过的对象,需要获取原始 BaseMapper 类型 + final Class> usefulClass = (Class>) ClassUtil.getUsefulClass(getMapper().getClass()); + return SqlUtil.toBool(Arrays.stream(Db.executeBatch(entityList.size(), batchSize, usefulClass, (mapper, index) -> mapper.update(entityList.get(index)))).sum()); + }); + } + /** * 根据数据主键更新数据。 *