All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hiboot.mcn.autoconfigure.mybatis.MybatisMultipleDataSourceAutoConfiguration Maven / Gradle / Ivy

package cn.hiboot.mcn.autoconfigure.mybatis;

import cn.hiboot.mcn.autoconfigure.config.ConfigProperties;
import cn.hiboot.mcn.autoconfigure.jdbc.MultipleDataSourceAutoConfiguration;
import cn.hiboot.mcn.autoconfigure.jdbc.MultipleDataSourceConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.mybatis.spring.mapper.ClassPathMapperScanner;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;

import java.io.IOException;

/**
 * MultipleDataSourceAutoConfiguration
 *
 * @author DingHao
 * @since 2022/1/2 22:21
 */
@AutoConfiguration(after = {MultipleDataSourceAutoConfiguration.class, MybatisAutoConfiguration.class})
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class,HikariDataSource.class})
@ConditionalOnProperty(prefix = ConfigProperties.MYBATIS_MULTIPLE_DATASOURCE_PREFIX,name = "enabled",havingValue = "true")
@ConditionalOnBean(MultipleDataSourceConfig.class)
@Import(MybatisMultipleDataSourceAutoConfiguration.MybatisMultipleDataSourceConfig.class)
public class MybatisMultipleDataSourceAutoConfiguration {

    protected static class MybatisMultipleDataSourceConfig implements ImportBeanDefinitionRegistrar {
        private final ResourceLoader resourceLoader;
        private final String basePackage;
        private final MultipleDataSourceConfig multipleDataSourceConfig;

        public MybatisMultipleDataSourceConfig(ResourceLoader resourceLoader, BeanFactory beanFactory) {
            this.resourceLoader = resourceLoader;
            this.multipleDataSourceConfig = beanFactory.getBean(MultipleDataSourceConfig.class);
            this.basePackage = multipleDataSourceConfig.getBasePackage();
        }

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){
            ResourcePatternResolver pathResolver = new PathMatchingResourcePatternResolver();
            multipleDataSourceConfig.getProperties().forEach((dsName,ds) -> {
                String sqlSessionFactoryName = dsName + "SqlSessionFactory";
                scanMapper(registry,sqlSessionFactoryName,basePackage + "." + multipleDataSourceConfig.getDaoPackageName() + "." + dsName);
                registry.registerBeanDefinition(dsName + "SqlSessionTemplate", BeanDefinitionBuilder.genericBeanDefinition(SqlSessionTemplate.class)
                        .addConstructorArgReference(sqlSessionFactoryName)
                        .getBeanDefinition());
                registry.registerBeanDefinition(sqlSessionFactoryName,buildDefinition(pathResolver, dsName));

            });
        }

        private BeanDefinition buildDefinition(ResourcePatternResolver pathResolver, String dsName){
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlSessionFactoryBean.class);
            Resource[] resources = getResources(pathResolver, dsName);
            if(resources != null){
                beanDefinitionBuilder.addPropertyValue("mapperLocations", resources);
            }
            org.apache.ibatis.session.Configuration conf = new org.apache.ibatis.session.Configuration();
            conf.setMapUnderscoreToCamelCase(true);
            beanDefinitionBuilder
                    .addPropertyValue("dataSource", new RuntimeBeanReference(ConfigProperties.getDataSourceBeanName(dsName)))
                    .addPropertyValue("vfs", SpringBootVFS.class)
                    .addPropertyValue("typeAliasesPackage", basePackage + ".bean." + dsName)
                    .addPropertyValue("typeHandlersPackage", basePackage + "." + multipleDataSourceConfig.getDaoPackageName() + ".handler." + dsName)
                    .addPropertyValue("configuration", conf);
            return beanDefinitionBuilder.getBeanDefinition();
        }

        private Resource[] getResources(ResourcePatternResolver pathResolver, String dsName){
            try {
                return pathResolver.getResources("classpath:mapper/" + dsName + "/*.xml");
            } catch (IOException e) {
                return null;
            }
        }

        private void scanMapper(BeanDefinitionRegistry registry, String sqlSessionFactoryName, String pkg){
            ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
            if (resourceLoader != null) {
                scanner.setResourceLoader(resourceLoader);
            }
            scanner.setBeanNameGenerator(FullyQualifiedAnnotationBeanNameGenerator.INSTANCE);
            scanner.setSqlSessionFactoryBeanName(sqlSessionFactoryName);
            scanner.registerFilters();
            scanner.doScan(pkg);
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy