咱們在開發一個項目的時候,可能會遇到須要對多個數據庫進行讀寫的需求,這時候就得在項目中配置多個數據源了。在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分包存放方便掃描以外,代碼上的編寫仍是和以前單數據源的時候同樣,因此這裏就不貼出業務代碼了。安全