diff --git a/main/manager-api/pom.xml b/main/manager-api/pom.xml index 098b0cef..b2ef83c8 100644 --- a/main/manager-api/pom.xml +++ b/main/manager-api/pom.xml @@ -20,10 +20,7 @@ 21 5.10.1 1.2.20 - 3.5.5 - mybatis-plus-boot-starter - 3.0.3 - src/mybatis-plus-legacy/java + 3.5.17 5.8.24 1.19.1 4.6.0 @@ -179,13 +176,13 @@ com.baomidou - ${mybatisplus.starter.artifactId} + mybatis-plus-spring-boot3-starter ${mybatisplus.version} - org.mybatis - mybatis-spring - ${mybatis-spring.version} + com.baomidou + mybatis-plus-jsqlparser-4.9 + ${mybatisplus.version} cn.hutool @@ -268,54 +265,9 @@ - - - - mybatis-plus-3.5.6 - - 3.5.6 - - - - - mybatis-plus-3.5.17 - - 3.5.17 - mybatis-plus-spring-boot3-starter - 3.0.5 - src/mybatis-plus-modern/java - - - - com.baomidou - mybatis-plus-jsqlparser-4.9 - ${mybatisplus.version} - - - - ${project.artifactId} - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.0 - - - add-mybatis-plus-compatibility-sources - generate-sources - - add-source - - - - ${project.basedir}/${mybatisplus.compat.source} - - - - - org.springframework.boot spring-boot-maven-plugin diff --git a/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java index c373b02b..30e610e1 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/common/service/impl/BaseServiceImpl.java @@ -5,7 +5,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; +import java.util.function.BiFunction; import org.apache.ibatis.binding.MapperMethod; import org.apache.ibatis.logging.Log; @@ -27,7 +27,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import xiaozhi.common.constant.Constant; -import xiaozhi.common.mybatisplus.MybatisPlusBatchHelper; import xiaozhi.common.page.PageData; import xiaozhi.common.service.BaseService; import xiaozhi.common.utils.ConvertUtils; @@ -182,9 +181,9 @@ public abstract class BaseServiceImpl, T> implements Bas * 执行批量操作 */ @SuppressWarnings("deprecation") - protected boolean executeBatch(Collection list, int batchSize, BiConsumer operation) { - return MybatisPlusBatchHelper.executeBatch(SqlHelper.sqlSessionFactory(this.currentModelClass()), this.log, - list, batchSize, operation); + protected boolean executeBatch(Collection list, int batchSize, BiFunction operation) { + return SqlHelper.executeBatch(SqlHelper.sqlSessionFactory(this.currentModelClass()), this.log, list, batchSize, + operation); } @Override @@ -211,7 +210,7 @@ public abstract class BaseServiceImpl, T> implements Bas return executeBatch(entityList, batchSize, (sqlSession, entity) -> { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); - sqlSession.update(sqlStatement, param); + return sqlSession.update(sqlStatement, param); }); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatAudioService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatAudioService.java index d7597243..816370a5 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatAudioService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatAudioService.java @@ -1,6 +1,7 @@ package xiaozhi.modules.agent.service; -import xiaozhi.common.mybatisplus.MpService; +import com.baomidou.mybatisplus.extension.repository.IRepository; + import xiaozhi.modules.agent.entity.AgentChatAudioEntity; /** @@ -10,7 +11,7 @@ import xiaozhi.modules.agent.entity.AgentChatAudioEntity; * @version 1.0, 2025/5/8 * @since 1.0.0 */ -public interface AgentChatAudioService extends MpService { +public interface AgentChatAudioService extends IRepository { /** * 保存音频数据 * diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatHistoryService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatHistoryService.java index 261cf161..0881356e 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatHistoryService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentChatHistoryService.java @@ -3,8 +3,9 @@ package xiaozhi.modules.agent.service; import java.util.List; import java.util.Map; +import com.baomidou.mybatisplus.extension.repository.IRepository; + import xiaozhi.common.page.PageData; -import xiaozhi.common.mybatisplus.MpService; import xiaozhi.modules.agent.dto.AgentChatHistoryDTO; import xiaozhi.modules.agent.dto.AgentChatSessionDTO; import xiaozhi.modules.agent.entity.AgentChatHistoryEntity; @@ -17,7 +18,7 @@ import xiaozhi.modules.agent.vo.AgentChatHistoryUserVO; * @version 1.0, 2025/4/30 * @since 1.0.0 */ -public interface AgentChatHistoryService extends MpService { +public interface AgentChatHistoryService extends IRepository { /** * 根据智能体ID获取会话列表 diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java index 25beb9cc..8e892ad7 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentPluginMappingService.java @@ -2,14 +2,15 @@ package xiaozhi.modules.agent.service; import java.util.List; -import xiaozhi.common.mybatisplus.MpService; +import com.baomidou.mybatisplus.extension.repository.IRepository; + import xiaozhi.modules.agent.entity.AgentPluginMapping; /** * @description 针对表【ai_agent_plugin_mapping(Agent与插件的唯一映射表)】的数据库操作Service * @createDate 2025-05-25 22:33:17 */ -public interface AgentPluginMappingService extends MpService { +public interface AgentPluginMappingService extends IRepository { /** * 根据智能体id获取插件参数 diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java index 09f4a4bd..89c780f7 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java @@ -1,6 +1,7 @@ package xiaozhi.modules.agent.service; -import xiaozhi.common.mybatisplus.MpService; +import com.baomidou.mybatisplus.extension.repository.IRepository; + import xiaozhi.modules.agent.entity.AgentTemplateEntity; /** @@ -8,7 +9,7 @@ import xiaozhi.modules.agent.entity.AgentTemplateEntity; * @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service * @createDate 2025-03-22 11:48:18 */ -public interface AgentTemplateService extends MpService { +public interface AgentTemplateService extends IRepository { /** * 获取默认模板 diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatAudioServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatAudioServiceImpl.java index 0799446c..7aeb7722 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatAudioServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatAudioServiceImpl.java @@ -2,7 +2,8 @@ package xiaozhi.modules.agent.service.impl; import org.springframework.stereotype.Service; -import xiaozhi.common.mybatisplus.MpServiceImpl; +import com.baomidou.mybatisplus.spring.repository.CrudRepository; + import xiaozhi.modules.agent.dao.AiAgentChatAudioDao; import xiaozhi.modules.agent.entity.AgentChatAudioEntity; import xiaozhi.modules.agent.service.AgentChatAudioService; @@ -15,7 +16,7 @@ import xiaozhi.modules.agent.service.AgentChatAudioService; * @since 1.0.0 */ @Service -public class AgentChatAudioServiceImpl extends MpServiceImpl +public class AgentChatAudioServiceImpl extends CrudRepository implements AgentChatAudioService { @Override public String saveAudio(byte[] audioData) { diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatHistoryServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatHistoryServiceImpl.java index ff4c7126..2183f98d 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatHistoryServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentChatHistoryServiceImpl.java @@ -14,8 +14,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.spring.repository.CrudRepository; + import xiaozhi.common.constant.Constant; -import xiaozhi.common.mybatisplus.MpServiceImpl; import xiaozhi.common.page.PageData; import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.JsonUtils; @@ -38,7 +39,7 @@ import xiaozhi.modules.agent.vo.AgentChatHistoryUserVO; */ @Service @RequiredArgsConstructor -public class AgentChatHistoryServiceImpl extends MpServiceImpl +public class AgentChatHistoryServiceImpl extends CrudRepository implements AgentChatHistoryService { private final AgentChatTitleService agentChatTitleService; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java index 4305cf6c..7a518fb1 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java @@ -9,10 +9,11 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.spring.repository.CrudRepository; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import xiaozhi.common.utils.JsonUtils; -import xiaozhi.common.mybatisplus.MpServiceImpl; import xiaozhi.modules.agent.dao.AgentPluginMappingMapper; import xiaozhi.modules.agent.entity.AgentPluginMapping; import xiaozhi.modules.agent.service.AgentPluginMappingService; @@ -28,7 +29,7 @@ import xiaozhi.modules.model.service.ModelConfigService; @Service @RequiredArgsConstructor @Slf4j -public class AgentPluginMappingServiceImpl extends MpServiceImpl +public class AgentPluginMappingServiceImpl extends CrudRepository implements AgentPluginMappingService { private final AgentPluginMappingMapper agentPluginMappingMapper; private final KnowledgeBaseService knowledgeBaseService; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java index 615b80c2..cfeb620c 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java @@ -16,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.repository.IRepository; import lombok.AllArgsConstructor; import xiaozhi.common.constant.Constant; @@ -482,10 +483,10 @@ public class AgentServiceImpl extends BaseServiceImpl imp .toList(); if (!toUpdate.isEmpty()) { - agentPluginMappingService.updateBatchById(toUpdate); + agentPluginMappingService.updateBatchById(toUpdate, IRepository.DEFAULT_BATCH_SIZE); } if (!toInsert.isEmpty()) { - agentPluginMappingService.saveBatch(toInsert); + agentPluginMappingService.saveBatch(toInsert, IRepository.DEFAULT_BATCH_SIZE); } // 5. 删除本次不在提交列表里的插件映射 @@ -494,7 +495,7 @@ public class AgentServiceImpl extends BaseServiceImpl imp .map(AgentPluginMapping::getId) .toList(); if (!toDelete.isEmpty()) { - agentPluginMappingService.removeBatchByIds(toDelete); + agentPluginMappingService.removeByIds(toDelete); } } @@ -687,7 +688,7 @@ public class AgentServiceImpl extends BaseServiceImpl imp toInsert.add(mapping); } // 保存默认插件 - agentPluginMappingService.saveBatch(toInsert); + agentPluginMappingService.saveBatch(toInsert, IRepository.DEFAULT_BATCH_SIZE); agentSnapshotService.createSnapshot(entity.getId(), "initial"); return entity.getId(); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java index 5b97122b..0cab47fb 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java @@ -26,6 +26,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.repository.IRepository; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -612,7 +613,7 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl +public class AgentTemplateServiceImpl extends CrudRepository implements AgentTemplateService { /** diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentVoicePrintServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentVoicePrintServiceImpl.java index 21314f52..801db0c1 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentVoicePrintServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentVoicePrintServiceImpl.java @@ -22,11 +22,12 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.spring.repository.CrudRepository; + import lombok.extern.slf4j.Slf4j; import xiaozhi.common.constant.Constant; import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.RenException; -import xiaozhi.common.mybatisplus.MpServiceImpl; import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.JsonUtils; import xiaozhi.modules.agent.dao.AgentVoicePrintDao; @@ -45,7 +46,7 @@ import xiaozhi.modules.sys.service.SysParamsService; */ @Service @Slf4j -public class AgentVoicePrintServiceImpl extends MpServiceImpl +public class AgentVoicePrintServiceImpl extends CrudRepository implements AgentVoicePrintService { private final AgentChatAudioService agentChatAudioService; private final RestTemplate restTemplate; diff --git a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpService.java b/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpService.java deleted file mode 100644 index 65e5c8b9..00000000 --- a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpService.java +++ /dev/null @@ -1,7 +0,0 @@ -package xiaozhi.common.mybatisplus; - -/** - * Stable project-level alias for the MyBatis-Plus service contract used by 3.5.5 and 3.5.6. - */ -public interface MpService extends com.baomidou.mybatisplus.extension.service.IService { -} diff --git a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpServiceImpl.java b/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpServiceImpl.java deleted file mode 100644 index 421588fb..00000000 --- a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MpServiceImpl.java +++ /dev/null @@ -1,10 +0,0 @@ -package xiaozhi.common.mybatisplus; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; - -/** - * Stable project-level base class for the MyBatis-Plus 3.5.5/3.5.6 service implementation. - */ -public class MpServiceImpl, T> - extends com.baomidou.mybatisplus.extension.service.impl.ServiceImpl implements MpService { -} diff --git a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java b/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java deleted file mode 100644 index 2350f24e..00000000 --- a/main/manager-api/src/mybatis-plus-legacy/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java +++ /dev/null @@ -1,24 +0,0 @@ -package xiaozhi.common.mybatisplus; - -import java.util.Collection; -import java.util.function.BiConsumer; - -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; - -import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; - -/** - * Type-safe access to the MyBatis-Plus 3.5.5/3.5.6 batch callback API. - */ -public final class MybatisPlusBatchHelper { - private MybatisPlusBatchHelper() { - } - - @SuppressWarnings("deprecation") - public static boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Collection entities, - int batchSize, BiConsumer operation) { - return SqlHelper.executeBatch(sqlSessionFactory, log, entities, batchSize, operation); - } -} diff --git a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpService.java b/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpService.java deleted file mode 100644 index 23bfeca6..00000000 --- a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpService.java +++ /dev/null @@ -1,7 +0,0 @@ -package xiaozhi.common.mybatisplus; - -/** - * Stable project-level alias for the MyBatis-Plus 3.5.17 Spring service contract. - */ -public interface MpService extends com.baomidou.mybatisplus.spring.service.IService { -} diff --git a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpServiceImpl.java b/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpServiceImpl.java deleted file mode 100644 index fd1fb2f6..00000000 --- a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MpServiceImpl.java +++ /dev/null @@ -1,10 +0,0 @@ -package xiaozhi.common.mybatisplus; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; - -/** - * Stable project-level base class for the MyBatis-Plus 3.5.17 Spring service implementation. - */ -public class MpServiceImpl, T> - extends com.baomidou.mybatisplus.spring.service.impl.ServiceImpl implements MpService { -} diff --git a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java b/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java deleted file mode 100644 index 690fee97..00000000 --- a/main/manager-api/src/mybatis-plus-modern/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelper.java +++ /dev/null @@ -1,27 +0,0 @@ -package xiaozhi.common.mybatisplus; - -import java.util.Collection; -import java.util.function.BiConsumer; - -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; - -import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; - -/** - * Type-safe access to the MyBatis-Plus 3.5.17 batch callback API. - */ -public final class MybatisPlusBatchHelper { - private MybatisPlusBatchHelper() { - } - - @SuppressWarnings("deprecation") - public static boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Collection entities, - int batchSize, BiConsumer operation) { - return SqlHelper.executeBatch(sqlSessionFactory, log, entities, batchSize, (sqlSession, entity) -> { - operation.accept(sqlSession, entity); - return 0; - }); - } -} diff --git a/main/manager-api/src/test/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelperTest.java b/main/manager-api/src/test/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelperTest.java deleted file mode 100644 index 692d56c7..00000000 --- a/main/manager-api/src/test/java/xiaozhi/common/mybatisplus/MybatisPlusBatchHelperTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package xiaozhi.common.mybatisplus; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.ibatis.executor.BatchResult; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.session.ExecutorType; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import org.junit.jupiter.api.Test; - -class MybatisPlusBatchHelperTest { - - @Test - void executesBatchThroughSelectedVersionAdapter() { - SqlSessionFactory sqlSessionFactory = mock(SqlSessionFactory.class); - SqlSession sqlSession = mock(SqlSession.class); - Log log = mock(Log.class); - when(sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(sqlSession); - - BatchResult batchResult = new BatchResult(mock(MappedStatement.class), "INSERT"); - batchResult.setUpdateCounts(new int[] { 1, 1 }); - when(sqlSession.flushStatements()).thenReturn(List.of(batchResult)); - - List processed = new ArrayList<>(); - boolean result = MybatisPlusBatchHelper.executeBatch(sqlSessionFactory, log, List.of("first", "second"), 2, - (session, entity) -> { - assertSame(sqlSession, session); - processed.add(entity); - }); - - assertTrue(result); - assertEquals(List.of("first", "second"), processed); - verify(sqlSession).flushStatements(); - verify(sqlSession).commit(true); - verify(sqlSession).close(); - } -} diff --git a/main/manager-api/src/test/java/xiaozhi/common/service/impl/BaseServiceImplTest.java b/main/manager-api/src/test/java/xiaozhi/common/service/impl/BaseServiceImplTest.java new file mode 100644 index 00000000..363065ec --- /dev/null +++ b/main/manager-api/src/test/java/xiaozhi/common/service/impl/BaseServiceImplTest.java @@ -0,0 +1,200 @@ +package xiaozhi.common.service.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; + +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.executor.BatchResult; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +import com.baomidou.mybatisplus.core.enums.SqlMethod; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; + +class BaseServiceImplTest { + private static final String INSERT_STATEMENT = TestMapper.class.getName() + ".insert"; + private static final String UPDATE_STATEMENT = TestMapper.class.getName() + ".updateById"; + + private final TestService service = new TestService(); + + @AfterEach + void clearTransactionSynchronization() { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.clearSynchronization(); + } + } + + @Test + void insertBatchFlushesAtTheRequestedBatchSizeAndCommitsWithoutATransaction() { + SqlSessionFactory sqlSessionFactory = mock(SqlSessionFactory.class); + SqlSession sqlSession = mock(SqlSession.class); + when(sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(sqlSession); + when(sqlSession.insert(eq(INSERT_STATEMENT), any(TestEntity.class))).thenReturn(1); + when(sqlSession.flushStatements()) + .thenReturn(List.of(batchResult(1, 1)), List.of(batchResult(1))); + + TestEntity first = new TestEntity(1L); + TestEntity second = new TestEntity(2L); + TestEntity third = new TestEntity(3L); + + try (MockedStatic sqlHelper = sqlHelperUsing(sqlSessionFactory)) { + assertTrue(service.insertBatch(List.of(first, second, third), 2)); + } + + verify(sqlSession).insert(INSERT_STATEMENT, first); + verify(sqlSession).insert(INSERT_STATEMENT, second); + verify(sqlSession).insert(INSERT_STATEMENT, third); + verify(sqlSession, times(2)).flushStatements(); + verify(sqlSession).commit(true); + verify(sqlSession).close(); + } + + @Test + void updateBatchByIdPassesEachEntityAndReturnsSuccessfulFlushResult() { + SqlSessionFactory sqlSessionFactory = mock(SqlSessionFactory.class); + SqlSession sqlSession = mock(SqlSession.class); + when(sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(sqlSession); + when(sqlSession.update(eq(UPDATE_STATEMENT), any())).thenReturn(1); + when(sqlSession.flushStatements()).thenReturn(List.of(batchResult(1, 1))); + + TestEntity first = new TestEntity(1L); + TestEntity second = new TestEntity(2L); + + try (MockedStatic sqlHelper = sqlHelperUsing(sqlSessionFactory)) { + assertTrue(service.updateBatchById(List.of(first, second), 10)); + } + + ArgumentCaptor params = ArgumentCaptor.forClass(Object.class); + verify(sqlSession, times(2)).update(eq(UPDATE_STATEMENT), params.capture()); + assertSame(first, entityFrom(params.getAllValues().get(0))); + assertSame(second, entityFrom(params.getAllValues().get(1))); + verify(sqlSession).flushStatements(); + } + + @Test + void batchCallbacksReturnActualAffectedRowCounts() { + SqlSession sqlSession = mock(SqlSession.class); + when(sqlSession.insert(eq(INSERT_STATEMENT), any(TestEntity.class))).thenReturn(3); + when(sqlSession.update(eq(UPDATE_STATEMENT), any())).thenReturn(2); + CallbackCapturingTestService capturingService = new CallbackCapturingTestService(sqlSession); + TestEntity entity = new TestEntity(1L); + + assertTrue(capturingService.insertBatch(List.of(entity), 7)); + assertEquals(7, capturingService.batchSize); + assertEquals(List.of(3), capturingService.affectedRows); + + assertTrue(capturingService.updateBatchById(List.of(entity), 9)); + assertEquals(9, capturingService.batchSize); + assertEquals(List.of(2), capturingService.affectedRows); + } + + @Test + void emptyBatchesReturnFalseWithoutOpeningABatchSession() { + SqlSessionFactory sqlSessionFactory = mock(SqlSessionFactory.class); + + try (MockedStatic sqlHelper = sqlHelperUsing(sqlSessionFactory)) { + assertFalse(service.insertBatch(List.of(), 10)); + assertFalse(service.updateBatchById(List.of(), 10)); + } + + verifyNoInteractions(sqlSessionFactory); + } + + @Test + void activeTransactionSynchronizationUsesTransactionAwareCommitAndLifecycle() { + SqlSessionFactory sqlSessionFactory = mock(SqlSessionFactory.class); + SqlSession sqlSession = mock(SqlSession.class); + when(sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(sqlSession); + when(sqlSession.insert(eq(INSERT_STATEMENT), any(TestEntity.class))).thenReturn(1); + when(sqlSession.flushStatements()).thenReturn(List.of(batchResult(1))); + TransactionSynchronizationManager.initSynchronization(); + + try (MockedStatic sqlHelper = sqlHelperUsing(sqlSessionFactory)) { + assertTrue(service.insertBatch(List.of(new TestEntity(1L)), 1)); + } + + verify(sqlSession).flushStatements(); + verify(sqlSession).commit(false); + verify(sqlSession, never()).commit(true); + verify(sqlSession, never()).close(); + } + + @SuppressWarnings("deprecation") + private static MockedStatic sqlHelperUsing(SqlSessionFactory sqlSessionFactory) { + MockedStatic sqlHelper = mockStatic(SqlHelper.class, CALLS_REAL_METHODS); + sqlHelper.when(() -> SqlHelper.sqlSessionFactory(TestEntity.class)).thenReturn(sqlSessionFactory); + return sqlHelper; + } + + private static BatchResult batchResult(int... updateCounts) { + BatchResult result = new BatchResult(mock(MappedStatement.class), "batch"); + result.setUpdateCounts(updateCounts); + return result; + } + + private static Object entityFrom(Object parameter) { + assertTrue(parameter instanceof MapperMethod.ParamMap); + return ((Map) parameter).get(Constants.ENTITY); + } + + private interface TestMapper extends BaseMapper { + } + + private record TestEntity(Long id) { + } + + private static class TestService extends BaseServiceImpl { + @Override + protected String getSqlStatement(SqlMethod sqlMethod) { + return switch (sqlMethod) { + case INSERT_ONE -> INSERT_STATEMENT; + case UPDATE_BY_ID -> UPDATE_STATEMENT; + default -> throw new IllegalArgumentException("Unexpected SQL method: " + sqlMethod); + }; + } + } + + private static class CallbackCapturingTestService extends TestService { + private final SqlSession sqlSession; + private int batchSize; + private List affectedRows; + + private CallbackCapturingTestService(SqlSession sqlSession) { + this.sqlSession = sqlSession; + } + + @Override + protected boolean executeBatch(Collection list, int batchSize, + BiFunction operation) { + this.batchSize = batchSize; + this.affectedRows = list.stream().map(entity -> operation.apply(sqlSession, entity)).toList(); + return true; + } + } +} diff --git a/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java b/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java index c822358c..8a3473e6 100644 --- a/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java +++ b/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.repository.IRepository; import com.fasterxml.jackson.core.type.TypeReference; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; @@ -1172,7 +1173,7 @@ class AgentSnapshotServiceImplTest { && "普通话".equals(agent.getTtsLanguage()) && "".equals(agent.getSummaryMemory()) && Integer.valueOf(0).equals(agent.getChatHistoryConf()))); - inOrder.verify(pluginMappingService).saveBatch(any()); + inOrder.verify(pluginMappingService).saveBatch(any(), eq(IRepository.DEFAULT_BATCH_SIZE)); inOrder.verify(snapshotService).createSnapshot(agentId, "initial"); } @@ -1407,7 +1408,7 @@ class AgentSnapshotServiceImplTest { return mapping != null && "plugin".equals(mapping.getPluginId()) && mapping.getParamInfo().contains("target"); - })); + }), eq(IRepository.DEFAULT_BATCH_SIZE)); verify(snapshotDao).insertWithNextVersion(argThat(snapshot -> "restore".equals(snapshot.getSource()))); }