Springboot 配置多个数据源,同时使用hibernate和mybatis

项目中经常会碰到,多个同类型数据库,或者不同类型数据库同时使用的情况。
最近就碰到,springboot 下,使用多个数据库的情形。
具体操作如下:
我用到了jpa和mybatis调用不同数据库的情形,配置三套数据源。
pom配置如下:

 
 
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
		    org.mybatis.spring.boot
		    mybatis-spring-boot-starter
		    2.0.0
		
        
            org.springframework.boot
            spring-boot-starter-security
        

        
            mysql
            mysql-connector-java
            runtime
        
        
        
            com.alibaba
            druid-spring-boot-starter
            ${druid.version}
        

application.properties 配置:

#server.port=25004

#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#spring.datasource.billsystem.db-type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.billsystem.jdbcUrl=jdbc:log4jdbc:mysql://10.0.17.10:3306/uaserver?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
spring.datasource.billsystem.username=root
spring.datasource.billsystem.password=lxdb2019@
spring.datasource.billsystem.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.billsystem.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.billsystem.filters=stat
spring.datasource.billsystem.initial-size=3
spring.datasource.billsystem.max-active=15
spring.datasource.billsystem.max-pool-prepared-statement-per-connection-size=20
spring.datasource.billsystem.max-wait=5000
spring.datasource.billsystem.min-evictable-idle-time-millis=300000
spring.datasource.billsystem.min-idle=3
spring.datasource.billsystem.pool-prepared-statements=true
spring.datasource.billsystem.stat-view-servlet.enabled= true
spring.datasource.billsystem.stat-view-servlet.login-password=123456
spring.datasource.billsystem.stat-view-servlet.login-username=druid
spring.datasource.billsystem.stat-view-servlet.reset-enable=false
spring.datasource.billsystem.stat-view-servlet.url-pattern=/druid/*
spring.datasource.billsystem.test-on-borrow=false
spring.datasource.billsystem.test-on-return=false
spring.datasource.billsystem.test-while-idle=true
spring.datasource.billsystem.time-between-eviction-runs-millis=90000
spring.datasource.billsystem.validation-query=select 1
spring.datasource.billsystem.web-stat-filter.enabled=true
spring.datasource.billsystem.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.billsystem.web-stat-filter.session-stat-enable=true
spring.datasource.billsystem.web-stat-filter.session-stat-max-count=1000
spring.datasource.billsystem.web-stat-filter.url-pattern=/*

#spring.datasource.nsradius.db-type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.nsradius.jdbcUrl=jdbc:log4jdbc:mysql://10.0.17.10:3306/lxwisdom?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
spring.datasource.nsradius.username=root
spring.datasource.nsradius.password=lxdb2019@
spring.datasource.nsradius.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.nsradius.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.nsradius.filters=stat
spring.datasource.nsradius.initial-size=3
spring.datasource.nsradius.max-active=15
spring.datasource.nsradius.max-pool-prepared-statement-per-connection-size=20
spring.datasource.nsradius.max-wait=5000
spring.datasource.nsradius.min-evictable-idle-time-millis=300000
spring.datasource.nsradius.min-idle=3
spring.datasource.nsradius.pool-prepared-statements=true
spring.datasource.nsradius.stat-view-servlet.enabled= true
spring.datasource.nsradius.stat-view-servlet.login-password=123456
spring.datasource.nsradius.stat-view-servlet.login-username=druid
spring.datasource.nsradius.stat-view-servlet.reset-enable=false
spring.datasource.nsradius.stat-view-servlet.url-pattern=/druid/*
spring.datasource.nsradius.test-on-borrow=false
spring.datasource.nsradius.test-on-return=false
spring.datasource.nsradius.test-while-idle=true
spring.datasource.nsradius.time-between-eviction-runs-millis=90000
spring.datasource.nsradius.validation-query=select 1
spring.datasource.nsradius.web-stat-filter.enabled=true
spring.datasource.nsradius.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.nsradius.web-stat-filter.session-stat-enable=true
spring.datasource.nsradius.web-stat-filter.session-stat-max-count=1000
spring.datasource.nsradius.web-stat-filter.url-pattern=/*

#spring.datasource.roma.db-type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.roma.jdbcUrl=jdbc:log4jdbc:mysql://10.0.17.10:3306/roma_db?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
spring.datasource.roma.username=root
spring.datasource.roma.password=lxdb2019@
spring.datasource.roma.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.roma.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.roma.filters=stat
spring.datasource.roma.initial-size=3
spring.datasource.roma.max-active=15
spring.datasource.roma.max-pool-prepared-statement-per-connection-size=20
spring.datasource.roma.max-wait=5000
spring.datasource.roma.min-evictable-idle-time-millis=300000
spring.datasource.roma.min-idle=3
spring.datasource.roma.pool-prepared-statements=true
spring.datasource.roma.stat-view-servlet.enabled= true
spring.datasource.roma.stat-view-servlet.login-password=123456
spring.datasource.roma.stat-view-servlet.login-username=druid
spring.datasource.roma.stat-view-servlet.reset-enable=false
spring.datasource.roma.stat-view-servlet.url-pattern=/druid/*
spring.datasource.roma.test-on-borrow=false
spring.datasource.roma.test-on-return=false
spring.datasource.roma.test-while-idle=true
spring.datasource.roma.time-between-eviction-runs-millis=90000
spring.datasource.roma.validation-query=select 1
spring.datasource.roma.web-stat-filter.enabled=true
spring.datasource.roma.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.roma.web-stat-filter.session-stat-enable=true
spring.datasource.roma.web-stat-filter.session-stat-max-count=1000
spring.datasource.roma.web-stat-filter.url-pattern=/*

**创建数据源配置类:**配置三个数据源。第一个是主数据源用@ Primary标签(当一个方法有多个实现类时,在方法中注入了多个,@primary可以指定注入哪一个。
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用
@Autowired @Qualifier(“personDaoBean”) 存在多个实例配合使用)

package com.isszwy.ioc.datasource.common.config;


import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class DruidDataSourceConfig {

    @Bean(name = "billSystemDataSource")
    @Qualifier("billSystemDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.billsystem")
    public DataSource billSystemDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "nsradiusDataSource")
    @Qualifier("nsradiusDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.nsradius")
    public DataSource nsradiusDataSource(){
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "romaDataSource")
    @Qualifier("romaDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.roma")
    public DataSource romaDataSource(){
        return DataSourceBuilder.create().build();
    }
}

数据源1

package com.isszwy.ioc.datasource.common.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "billSystemEntityManagerFactoryBean",
        transactionManagerRef = "billSystemTransactionManager",
        //设置Repository所在位置
        basePackages = {"me.zhengjie.modules.system.repository","com.isszwy.ioc.ua.repository",
        "me.zhengjie.modules.monitor.repository","me.zhengjie.repository","me.zhengjie.modules.quartz.repository"})
public class BillSystemDataSourceConfig {
    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    private HibernateProperties hibernateProperties;

    @Autowired
    @Qualifier("billSystemDataSource")
    private DataSource billSystemDataSource;

    @Bean(name = "billSystemEntityManagerFactoryBean")
    @Primary
    public LocalContainerEntityManagerFactoryBean billSystemEntityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder.dataSource(billSystemDataSource)
                .properties(getVendorProperties(billSystemDataSource))
                //设置实体类所在位置
                .packages("com.isszwy.ioc.ua.domain","me.zhengjie.modules.system.domain",
                        "me.zhengjie.modules.monitor.domain","me.zhengjie.modules.quartz.domain","me.zhengjie.domain")
                .persistenceUnit("billSystemPersistenceUnit")
                .build();
    }

    private Map getVendorProperties(DataSource dataSource){
       // return jpaProperties.getHibernateProperties(dataSource);
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    /**
     * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
     * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
     * mybatis的sqlSession.
     * @param builder
     * @return
     */
    @Bean(name = "billSystemEntityManagerFactory")
    public EntityManagerFactory billSystemEntityManagerFactory(EntityManagerFactoryBuilder builder){
        return this.billSystemEntityManagerFactoryBean(builder).getObject();
    }

    /**
     * 配置事物管理器
     */
    @Bean(name = "billSystemTransactionManager")
    public PlatformTransactionManager billSystemTransactionManager(EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(billSystemEntityManagerFactory(builder));
    }
}

数据源2

package com.isszwy.ioc.datasource.common.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "nsradiusEntityManagerFactoryBean",
        transactionManagerRef = "nsradiusTransactionManager",
        //设置Repository所在位置
        basePackages = {"me.zhengjie.visual.staticdata.repository"})
public class NsradiusDataSourceConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    private HibernateProperties hibernateProperties;

    @Autowired
    @Qualifier("nsradiusDataSource")
    private DataSource nsradiusDataSource;

    @Bean(name = "nsradiusEntityManagerFactoryBean")
    public LocalContainerEntityManagerFactoryBean nsradiusEntityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder.dataSource(nsradiusDataSource)
                .properties(getVendorProperties(nsradiusDataSource))
                //设置实体类所在位置
                .packages("me.zhengjie.visual.staticdata.domain")
                .persistenceUnit("nsradiusPersistenceUnit")
                .build();
    }

    private Map getVendorProperties(DataSource dataSource){
        // return jpaProperties.getHibernateProperties(dataSource);
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    /**
     * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
     * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
     * mybatis的sqlSession.
     */
    @Bean(name = "nsradiusEntityManagerFactory")
    public EntityManagerFactory nsradiusEntityManagerFactory(EntityManagerFactoryBuilder builder){
        return this.nsradiusEntityManagerFactoryBean(builder).getObject();
    }

    /**
     * 配置事物管理器
     */
    @Bean(name = "nsradiusTransactionManager")
    public PlatformTransactionManager nsradiusTransactionManager(EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(nsradiusEntityManagerFactory(builder));
    }
}

数据源3

package com.isszwy.ioc.datasource.common.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "me.zhengjie.roma.statistics.mapper", sqlSessionFactoryRef = "mybatisSessionFactory")
public class RomaDataSourceConfig {
	private static final String MAPPER_LOCATION = "classpath*:mybatis/mapper/*.xml";

	@Autowired
	@Qualifier("romaDataSource")
	private DataSource mybatisDataSource;

	@Bean(name = "mybatisTransactionManager")
	public DataSourceTransactionManager masterTransactionManager() {
		return new DataSourceTransactionManager(mybatisDataSource);
	}

	@Bean(name = "mybatisSessionFactory")
	public SqlSessionFactory mybatisSessionFactory() throws Exception {
		// 解决查询返回结果含null没有对应字段值问题
		org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
		configuration.setCallSettersOnNulls(true);
		// configuration.setMapUnderscoreToCamelCase(true);
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(mybatisDataSource);
		sessionFactory.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources(RomaDataSourceConfig.MAPPER_LOCATION));
		sessionFactory.setConfiguration(configuration);
		return sessionFactory.getObject();

	}

	@Bean
	public SqlSessionTemplate sqlSessionTemplate() throws Exception {
		return new SqlSessionTemplate(mybatisSessionFactory());
	}
}

注意在数据源1、2、3中配置对应的映射类和repository、或者mapper和mappper.xml的完整路径,才能在正常使用。还有配置主数据源也就是数据源1 的时候要在对应方法使用 @Primary,多数据源必须有一个主数据源,其他的数据源就不要用 @Primary了。

你可能感兴趣的:(mybatis,boot,dbcp,mysql,java)