1. 程式人生 > 實用技巧 >mybatis下實現多資料來源

mybatis下實現多資料來源

這次要完成的是從一個數據庫中讀取資料,然後再把資料插入到另一個數據庫中。在同一套專案程式碼中要完成這個操作,就不可避免的涉及到了多資料來源。本文即介紹在mybatis中完成多資料來源的切換相關內容

  1. 指定資料來源一

    @Configuration
    // 掃描 Mapper 介面並容器管理
    @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
    public class MasterDataSourceConfig {
    
        // 精確到 master 目錄,以便跟其他資料來源隔離
        static final String PACKAGE = "com.datareach.kafka.dao.master";
        static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
    	//application.yml中的值可以通過@Value註解進行讀取
        @Value("${master.datasource.url}")
        private String url;
        @Value("${master.datasource.username}")
        private String user;
        @Value("${master.datasource.password}")
        private String password;
        @Value("${master.datasource.driver-class-name}")
        private String driverClass;
    
        @Bean(name = "masterDataSource")
        @Primary
        public DataSource masterDataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driverClass);
            dataSource.setUrl(url);
            dataSource.setUsername(user);
            dataSource.setPassword(password);
            return dataSource;
        }
    
        @Bean(name = "masterTransactionManager")
        @Primary
        public DataSourceTransactionManager masterTransactionManager() {
            return new DataSourceTransactionManager(masterDataSource());
        }
    
        @Bean(name = "masterSqlSessionFactory")
        @Primary
        public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
                throws Exception {
            final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(masterDataSource);
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
            return sessionFactory.getObject();
        }
    }
    

    資料來源一的相關配置

    # master 資料來源配置
    master:
      datasource:
        url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
        driver-class-name: org.postgresql.Driver
        username: product
        password: 
        initial-size: 1
        min-idle: 1
        max-active: 20
        test-on-borrow: true
        max-wait: 60000
        time-between-eviction-runs-millis: 60000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        test-While-Idle: true
        test-on-return: false
        pool-prepared-statements: false
        max-pool-prepared-statement-per-connection-size: 20
        filters: stat,wall,log4j,config
    
  2. 指定資料來源二

    @Configuration
    // 掃描 Mapper 介面並容器管理
    @MapperScan(basePackages = SecondDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
    public class SecondDataSourceConfig {
        // 精確到 cluster 目錄,以便跟其他資料來源隔離
        static final String PACKAGE = "com.datareach.kafka.dao.secondary";
        static final String MAPPER_LOCATION = "classpath:mapper/secondary/*.xml";
        @Value("${second.datasource.url}")
        private String url;
        @Value("${second.datasource.username}")
        private String user;
        @Value("${second.datasource.password}")
        private String password;
        @Value("${second.datasource.driver-class-name}")
        private String driverClass;
    
        @Bean(name = "secondDataSource")
        public DataSource clusterDataSource() {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driverClass);
            dataSource.setUrl(url);
            dataSource.setUsername(user);
            dataSource.setPassword(password);
            return dataSource;
        }
        @Bean(name = "secondTransactionManager")
        public DataSourceTransactionManager clusterTransactionManager() {
            return new DataSourceTransactionManager(clusterDataSource());
        }
        @Bean(name = "secondSqlSessionFactory")
        public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("secondDataSource") DataSource clusterDataSource)
                throws Exception {
            final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(clusterDataSource);
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources(SecondDataSourceConfig.MAPPER_LOCATION));
            return sessionFactory.getObject();
        }
    }
    

    資料來源一的相關配置

    second:
      datasource:
        url: jdbc:mysql://localhost:40000/PG_Data?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: 
        driver-class-name: com.mysql.jdbc.Driver
        max-idle: 10
        max-wait: 10000
        min-idle: 5
        initial-size: 5
    

其實就是例項化了兩個SqlSessionFactory——masterSqlSessionFactory和secondSqlSessionFactory,然後通過註解@MapperScan指定掃描指定的mapper介面時用指定的SqlSessionFactory進行連線構建,從而實現了多資料來源。