咱们在开发一个项目的时候,可能会遇到须要对多个数据库进行读写的需求,这时候就得在项目中配置多个数据源了。在Java项目的开发中,目前最经常使用的数据操做框架是 Mybatis,开发框架也都基本用上了SpringBoot。而Druid号称最好的数据库链接池,天然也是被普遍使用。java
因此本文将演示一下,SpringBoot+Druid+Mybatis如何去配置多数据源。首先在IDEA中建立一个SpringBoot工程:mysql
选择一些基本的包:web
完成建立:spring
pom.xml配置的依赖以下:sql
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- alibaba的druid数据库链接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> </dependencies>
接着就是编辑SpringBoot的配置文件,我这里使用的是yml格式的。须要注意的是,在使用多数据源的状况下,必须区分出主数据源和从数据源,不然会报错。application.yml配置文件内容以下:数据库
spring: datasource: #使用druid链接池 type: com.alibaba.druid.pool.DruidDataSource # 自定义的主数据源配置信息 primary: datasource: #druid相关配置 druid: #监控统计拦截的filters filters: stat driverClassName: com.mysql.jdbc.Driver #配置基本属性 url: jdbc:mysql://127.0.0.1:3306/primary_database?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false username: root password: password #配置初始化大小/最小/最大 initialSize: 1 minIdle: 1 maxActive: 20 #获取链接等待超时时间 maxWait: 60000 #间隔多久进行一次检测,检测须要关闭的空闲链接 timeBetweenEvictionRunsMillis: 60000 #一个链接在池中最小生存的时间 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false #打开PSCache,并指定每一个链接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false poolPreparedStatements: false maxPoolPreparedStatementPerConnectionSize: 20 # 自定义的从数据源配置信息 back: datasource: #druid相关配置 druid: #监控统计拦截的filters filters: stat driverClassName: com.mysql.jdbc.Driver #配置基本属性 url: jdbc:mysql://127.0.0.1:3306/back_database?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false username: root password: password #配置初始化大小/最小/最大 initialSize: 1 minIdle: 1 maxActive: 20 #获取链接等待超时时间 maxWait: 60000 #间隔多久进行一次检测,检测须要关闭的空闲链接 timeBetweenEvictionRunsMillis: 60000 #一个链接在池中最小生存的时间 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false #打开PSCache,并指定每一个链接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false poolPreparedStatements: false maxPoolPreparedStatementPerConnectionSize: 20
而后在项目中新建一个config包,并在该包下建立一个PrimaryDataBaseConfig类,做为咱们的主数据源配置类,用于加载自定义的主数据源配置信息,以及建立数据源和会话链接工厂等实例:apache
package com.dabo.mini.game.zhaxinle.config; import com.alibaba.druid.pool.DruidDataSource; import lombok.Data; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; /** * @ProjectName zhaxinle * @Author: zeroJun * @Date: 2018/8/16 16:49 * @Description: 主数据源配置类 */ @Data @Configuration // 前缀为primary.datasource.druid的配置信息 @ConfigurationProperties(prefix = "primary.datasource.druid") @MapperScan(basePackages = PrimaryDataBaseConfig.PACKAGE, sqlSessionFactoryRef = "primarySqlSessionFactory") public class PrimaryDataBaseConfig { /** * dao层的包路径 */ static final String PACKAGE = "com.dabo.mini.game.zhaxinle.dao.primary"; /** * mapper文件的相对路径 */ private static final String MAPPER_LOCATION = "classpath:mappers/primary/*.xml"; private String filters; private String url; private String username; private String password; private String driverClassName; private int initialSize; private int minIdle; private int maxActive; private long maxWait; private long timeBetweenEvictionRunsMillis; private long minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; private boolean poolPreparedStatements; private int maxPoolPreparedStatementPerConnectionSize; // 主数据源使用@Primary注解进行标识 @Primary @Bean(name = "primaryDataSource") public DataSource primaryDataSource() throws SQLException { DruidDataSource druid = new DruidDataSource(); // 监控统计拦截的filters druid.setFilters(filters); // 配置基本属性 druid.setDriverClassName(driverClassName); druid.setUsername(username); druid.setPassword(password); druid.setUrl(url); //初始化时创建物理链接的个数 druid.setInitialSize(initialSize); //最大链接池数量 druid.setMaxActive(maxActive); //最小链接池数量 druid.setMinIdle(minIdle); //获取链接时最大等待时间,单位毫秒。 druid.setMaxWait(maxWait); //间隔多久进行一次检测,检测须要关闭的空闲链接 druid.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); //一个链接在池中最小生存的时间 druid.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); //用来检测链接是否有效的sql druid.setValidationQuery(validationQuery); //建议配置为true,不影响性能,而且保证安全性。 druid.setTestWhileIdle(testWhileIdle); //申请链接时执行validationQuery检测链接是否有效 druid.setTestOnBorrow(testOnBorrow); druid.setTestOnReturn(testOnReturn); //是否缓存preparedStatement,也就是PSCache,oracle设为true,mysql设为false。分库分表较多推荐设置为false druid.setPoolPreparedStatements(poolPreparedStatements); // 打开PSCache时,指定每一个链接上PSCache的大小 druid.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); return druid; } // 建立该数据源的事务管理 @Primary @Bean(name = "primaryTransactionManager") public DataSourceTransactionManager primaryTransactionManager() throws SQLException { return new DataSourceTransactionManager(primaryDataSource()); } // 建立Mybatis的链接会话工厂实例 @Primary @Bean(name = "primarySqlSessionFactory") public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(primaryDataSource); // 设置数据源bean sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(PrimaryDataBaseConfig.MAPPER_LOCATION)); // 设置mapper文件路径 return sessionFactory.getObject(); } }
一样的,还须要建立一个从数据源配置类,与主数据源配置类不一样的是,从数据源配置类不能使用@Primary
注解,即表示它是一个从数据源。代码以下:缓存
package com.dabo.mini.game.zhaxinle.config; import com.alibaba.druid.pool.DruidDataSource; import lombok.Data; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; 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 javax.sql.DataSource; import java.sql.SQLException; /** * @ProjectName zhaxinle * @Author: zeroJun * @Date: 2018/8/16 16:49 * @Description: 后台数据源配置类 */ @Data @Configuration @ConfigurationProperties(prefix = "back.datasource.druid") @MapperScan(basePackages = BackDataBaseConfig.PACKAGE, sqlSessionFactoryRef = "backSqlSessionFactory") public class BackDataBaseConfig { /** * dao层的包路径 */ static final String PACKAGE = "com.dabo.mini.game.zhaxinle.dao.back"; /** * mapper文件的相对路径 */ private static final String MAPPER_LOCATION = "classpath:mappers/back/*.xml"; private String filters; private String url; private String username; private String password; private String driverClassName; private int initialSize; private int minIdle; private int maxActive; private long maxWait; private long timeBetweenEvictionRunsMillis; private long minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; private boolean poolPreparedStatements; private int maxPoolPreparedStatementPerConnectionSize; @Bean(name = "backDataSource") public DataSource backDataSource() throws SQLException { DruidDataSource druid = new DruidDataSource(); // 监控统计拦截的filters druid.setFilters(filters); // 配置基本属性 druid.setDriverClassName(driverClassName); druid.setUsername(username); druid.setPassword(password); druid.setUrl(url); //初始化时创建物理链接的个数 druid.setInitialSize(initialSize); //最大链接池数量 druid.setMaxActive(maxActive); //最小链接池数量 druid.setMinIdle(minIdle); //获取链接时最大等待时间,单位毫秒。 druid.setMaxWait(maxWait); //间隔多久进行一次检测,检测须要关闭的空闲链接 druid.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); //一个链接在池中最小生存的时间 druid.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); //用来检测链接是否有效的sql druid.setValidationQuery(validationQuery); //建议配置为true,不影响性能,而且保证安全性。 druid.setTestWhileIdle(testWhileIdle); //申请链接时执行validationQuery检测链接是否有效 druid.setTestOnBorrow(testOnBorrow); druid.setTestOnReturn(testOnReturn); //是否缓存preparedStatement,也就是PSCache,oracle设为true,mysql设为false。分库分表较多推荐设置为false druid.setPoolPreparedStatements(poolPreparedStatements); // 打开PSCache时,指定每一个链接上PSCache的大小 druid.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); return druid; } @Bean(name = "backTransactionManager") public DataSourceTransactionManager backTransactionManager() throws SQLException { return new DataSourceTransactionManager(backDataSource()); } @Bean(name = "backSqlSessionFactory") public SqlSessionFactory backSqlSessionFactory(@Qualifier("backDataSource") DataSource backDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(backDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(BackDataBaseConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } }
完成以上配置后,该工程就具备链接两个数据库的能力了,若是要配置两个以上的数据库也是同样的,配置多个从数据源便可。业务代码层面除了须要将不一样的数据源相关的mapper、dao、pojo分包存放方便扫描以外,代码上的编写仍是和以前单数据源的时候同样,因此这里就不贴出业务代码了。安全