c2c网站类型,东莞建设建网站,图片上加语音 网站开发,电影网站如何做spring boot 测试 mybatis mapper类
针对 mybatis plus不启动 webserver指定加载 xml 【过滤 “classpath*:/mapper/**/*.xml” 下的xml】, mapper xml文件名和mapper java文件名称要一样#xff0c;是根据文件名称过滤的。默认情况加载和解析所有mapper.xml
自定义 MapperT…spring boot 测试 mybatis mapper类
针对 mybatis plus不启动 webserver指定加载 xml 【过滤 “classpath*:/mapper/**/*.xml” 下的xml】, mapper xml文件名和mapper java文件名称要一样是根据文件名称过滤的。默认情况加载和解析所有mapper.xml
自定义 MapperTest注解
/*** mapper 测试* 1.不启动 web容器* 2.指定加载xml* Date: 2024/12/2 9:16*/
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.TYPE)
Documented
SpringBootTest(webEnvironment SpringBootTest.WebEnvironment.NONE, classes {DataSourceAutoConfiguration.class,MybatisPlusTestAutoConfiguration.class,DataSource.class,SqlSessionFactory.class
})
MapperScan
Import(MybatisPlusTestAutoConfiguration.AutoConfiguredMapperScannerTestRegistrar.class)
public interface MapperTest {/*** 指定要加载的 Mapper class* return*/AliasFor(annotation MapperScan.class,attribute basePackageClasses)Class?[] mapperClasses() default {};}自定义 MybatisPlusTestAutoConfiguration
大部分 copy MybatisPlusAutoConfiguration, 就是增加过滤条件
import com.baomidou.mybatisplus.autoconfigure.*;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;/*** {link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a* {link SqlSessionFactory} and a {link SqlSessionTemplate}.* p* If {link org.mybatis.spring.annotation.MapperScan} is used, or a* configuration file is specified as a property, those will be considered,* otherwise this auto-configuration will attempt to register mappers based on* the interface definitions in or under the root auto-configuration package.* /p* p copy from {link org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration}/p** author Eddú Meléndez* author Josh Long* author Kazuki Shimizu* author Eduardo Macarrón*/
Configuration
ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
ConditionalOnSingleCandidate(DataSource.class)
EnableConfigurationProperties(MybatisPlusProperties.class)
AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusTestAutoConfiguration implements InitializingBean {private static final Logger logger LoggerFactory.getLogger(MybatisPlusTestAutoConfiguration.class);private final MybatisPlusProperties properties;private final Interceptor[] interceptors;private final TypeHandler[] typeHandlers;private final LanguageDriver[] languageDrivers;private final ResourceLoader resourceLoader;private final DatabaseIdProvider databaseIdProvider;private final ListConfigurationCustomizer configurationCustomizers;private final ListMybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizers;private final ApplicationContext applicationContext;private static ListString mapperClassResource new ArrayList();public MybatisPlusTestAutoConfiguration(MybatisPlusProperties properties,ObjectProviderInterceptor[] interceptorsProvider,ObjectProviderTypeHandler[] typeHandlersProvider,ObjectProviderLanguageDriver[] languageDriversProvider,ResourceLoader resourceLoader,ObjectProviderDatabaseIdProvider databaseIdProvider,ObjectProviderListConfigurationCustomizer configurationCustomizersProvider,ObjectProviderListMybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizerProvider,ApplicationContext applicationContext) {this.properties properties;this.interceptors interceptorsProvider.getIfAvailable();this.typeHandlers typeHandlersProvider.getIfAvailable();this.languageDrivers languageDriversProvider.getIfAvailable();this.resourceLoader resourceLoader;this.databaseIdProvider databaseIdProvider.getIfAvailable();this.configurationCustomizers configurationCustomizersProvider.getIfAvailable();this.mybatisPlusPropertiesCustomizers mybatisPlusPropertiesCustomizerProvider.getIfAvailable();this.applicationContext applicationContext;}Overridepublic void afterPropertiesSet() {if (!CollectionUtils.isEmpty(mybatisPlusPropertiesCustomizers)) {mybatisPlusPropertiesCustomizers.forEach(i - i.customize(properties));}checkConfigFileExists();}private void checkConfigFileExists() {if (this.properties.isCheckConfigLocation() StringUtils.hasText(this.properties.getConfigLocation())) {Resource resource this.resourceLoader.getResource(this.properties.getConfigLocation());Assert.state(resource.exists(),Cannot find config location: resource (please add config file or check your Mybatis configuration));}}SuppressWarnings(SpringJavaInjectionPointsAutowiringInspection)BeanConditionalOnMissingBeanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {// TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBeanMybatisSqlSessionFactoryBean factory new MybatisSqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}applyConfiguration(factory);if (this.properties.getConfigurationProperties() ! null) {factory.setConfigurationProperties(this.properties.getConfigurationProperties());}if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider ! null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (this.properties.getTypeAliasesSuperType() ! null) {factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.typeHandlers)) {factory.setTypeHandlers(this.typeHandlers);}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {Resource[] resources this.properties.resolveMapperLocations();if (!CollectionUtils.isEmpty(mapperClassResource)){ListResource collect Arrays.stream(resources).filter(r - {String f r.getFilename().substring(0, r.getFilename().lastIndexOf(.));// 过滤 xmlif (mapperClassResource.contains(f)) {return true;}return false;}).peek(r - {logger.info(load xml: {}, r.getFilename());}).collect(Collectors.toList());if (!CollectionUtils.isEmpty(collect)){factory.setMapperLocations(collect.toArray(new Resource[0]));}else {factory.setMapperLocations(resources);}}else {factory.setMapperLocations(resources);}}// TODO 对源码做了一定的修改(因为源码适配了老旧的mybatis版本,但我们不需要适配)Class? extends LanguageDriver defaultLanguageDriver this.properties.getDefaultScriptingLanguageDriver();if (!ObjectUtils.isEmpty(this.languageDrivers)) {factory.setScriptingLanguageDrivers(this.languageDrivers);}Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);// TODO 自定义枚举包if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());}// TODO 此处必为非 NULLGlobalConfig globalConfig this.properties.getGlobalConfig();// TODO 注入填充器this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);// TODO 注入主键生成器this.getBeanThen(IKeyGenerator.class, i - globalConfig.getDbConfig().setKeyGenerator(i));// TODO 注入sql注入器this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);// TODO 注入ID生成器this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);// TODO 设置 GlobalConfig 到 MybatisSqlSessionFactoryBeanfactory.setGlobalConfig(globalConfig);return factory.getObject();}/*** 检查spring容器里是否有对应的bean,有则进行消费** param clazz class* param consumer 消费* param T 泛型*/private T void getBeanThen(ClassT clazz, ConsumerT consumer) {if (this.applicationContext.getBeanNamesForType(clazz, false, false).length 0) {consumer.accept(this.applicationContext.getBean(clazz));}}// TODO 入参使用 MybatisSqlSessionFactoryBeanprivate void applyConfiguration(MybatisSqlSessionFactoryBean factory) {// TODO 使用 MybatisConfigurationMybatisConfiguration configuration this.properties.getConfiguration();if (configuration null !StringUtils.hasText(this.properties.getConfigLocation())) {configuration new MybatisConfiguration();}if (configuration ! null !CollectionUtils.isEmpty(this.configurationCustomizers)) {for (ConfigurationCustomizer customizer : this.configurationCustomizers) {customizer.customize(configuration);}}factory.setConfiguration(configuration);}BeanConditionalOnMissingBeanpublic SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {ExecutorType executorType this.properties.getExecutorType();if (executorType ! null) {return new SqlSessionTemplate(sqlSessionFactory, executorType);} else {return new SqlSessionTemplate(sqlSessionFactory);}}/*** This will just scan the same base package as Spring Boot does. If you want more power, you can explicitly use* {link org.mybatis.spring.annotation.MapperScan} but this will get typed mappers working correctly, out-of-the-box,* similar to using Spring Data JPA repositories.*/public static class AutoConfiguredMapperScannerTestRegistrar implements ImportBeanDefinitionRegistrar {Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//从 MapperTest 加载要过滤的 mapperAnnotationAttributes mapperScanAttrs AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperTest.class.getName()));ListString collect Arrays.stream(mapperScanAttrs.getClassArray(mapperClasses)).map(clz - clz.getSimpleName()).collect(Collectors.toList());//指定要加载的 classmapperClassResource.addAll(collect);}}
}测试
MapperTest( mapperClasses {UserMapper.class
})
public class UserPermTest {Autowiredprivate UserMapper mapper;Testpublic void query() {LambdaQueryWrapperUserModel query Wrappers.lambdaQuery(UserModel.class);query.last( limit 2);ListUserModel list mapper.selectList(query);}
}测试成功看日志
INFO [main] i.f.b.c.MybatisPlusTestAutoConfiguration : load xml: UserMapper.xml