写在最前面
此文章讲述了多数据源配置,不太适用于主从数据库的配置
前言
之前的项目用到了多数据源,于是在网上搜了一些博客,发现照着写是可以,但测试的时候发现两个数据源却是同一个(或者是报错),经过调试,才发现是因为HikariCP。网上大多博客写的应该都是用的默认的tomcat-jdbc的连接池, (程序员DD的多数据源配置);也有用Druid 的(Mybatis+Druid多数据源),毕竟是阿里搞的,所以国内用的应该挺多。本文将介绍HikariCp的多数据源配置
上面的tomcat-jdbc的多数据源本人尝试配置过,是好使的;至于druid的,没尝试过,大家可以自行 调试哈
HikariCP
HikariCP是什么?是一个数据库连接池(并不是你们想的某岛国动作影星╭(╯^╰)╮)。据说是现阶段最快的了(反正我是信了)。官网地址http://brettwooldridge.github.io/HikariCP/
1. 启用HikariCP
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<!--去掉默认的tomcat-jdbc的依赖-->
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
2. 配置数据源
spring:
datasource:
url: jdbc:mysql://192.168.2.200:3306/union1?useUnicode=true&characterEncoding=GBK
username: qiji
password: qiji,123
driver-class-name: com.mysql.jdbc.Driver
hikari:
connection-test-query: SELECT 1 FROM DUAL
minimum-idle: 1
maximum-pool-size: 5
pool-name: bosPoolName
max-lifetime: 1800000
secondary:
url: jdbc:mysql://192.168.2.200:3306/b2c?useUnicode=true&characterEncoding=GBK
username: qiji
password: qiji,123
driver-class-name: com.mysql.jdbc.Driver
hikari:
connection-test-query: SELECT 1 FROM DUAL
minimum-idle: 1
maximum-pool-size: 5
pool-name: bosPoolName
max-lifetime: 1800000
关于配置的意思不过多解释了
3. DataSourceConfig代码
PrimaryDataSourceConfig.java
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class PrimaryDataSourceConfig extends DataSourceAutoConfiguration{
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix="spring.datasource.hikari")
public DataSource dataSource(DataSourceProperties properties){
return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class)
.driverClassName(properties.determineDriverClassName())
.url(properties.determineUrl()).username(properties.determineUsername()).password(properties.determinePassword()).build();
}
@Bean
@Primary
public JdbcTemplate jdbcTemplate(
@Qualifier("dataSource") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
SecondaryDataSourceConfig.java
package com.oqiji.union.dsconfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* Created by yangyang on 16/11/23.
*/
@Configuration
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class VipDataSourceConfig {
@Bean(name = "dataSourceSec")
@ConfigurationProperties(prefix="spring.datasource.secondary.hikari")
public DataSource secondaryDataSource(DataSourceProperties properties){
return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class)
.driverClassName(properties.determineDriverClassName())
.url(properties.determineUrl()).username(properties.determineUsername()).password(properties.determinePassword()).build();
}
@Bean(name = "jdbcTemplateSec")
public JdbcTemplate secondaryJdbcTemplate(
@Qualifier("dataSourceSec") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
此时配置的两个数据源已经可以使用了
@Autowired
@Qualifier("jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Autowired
@Qualifier("jdbcTemplateSec")
private JdbcTemplate jdbcTemplateSec;
4. JPA及事务配置
不同数据源对应的Model类和dao应放在不同的包下,以便JPA扫描配置
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
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.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
/**
* Created by yangyang on 16/11/23.
*/
@Configuration
@EnableJpaRepositories(
basePackages = {"com.oqiji.vs.auth.dao",
"com.oqiji.ud"})//设置dao(repo)所在位置
@Import({PrimaryDataSourceConfig.class})
@AutoConfigureAfter({PrimaryDataSourceConfig.class})
public class PrimaryRepositoryConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
@Bean(name = "entityManager")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(dataSource)
.properties(getVendorProperties(dataSource))
.packages("com.oqiji.ud.bean", "com.oqiji.jcommon.domain") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
@Bean(name = "transactionManager")
@Primary
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
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.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
/**
* Created by yangyang on 16/11/23.
*/
@Configuration
@EnableJpaRepositories(basePackages = {"com.oqiji.sec"})//设置dao(repo)所在位置
@Import({SecondaryDataSourceConfig.class})
@AutoConfigureAfter({SecondaryDataSourceConfig.class})
public class SecondaryRepositoryConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("secDataSource")
private DataSource dataSource;
@Bean(name = "secEntityManager")
public EntityManager secEntityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySec(builder).getObject().createEntityManager();
}
@Bean(name = "secEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySec(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secDataSource)
.properties(getVendorProperties(dataSource))
.packages("com.oqiji.sec.bean", "com.oqiji.sec.domain") //设置实体类所在位置
.persistenceUnit("secPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
@Bean(name = "secTransactionManager")
PlatformTransactionManager transactionManagerSec(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySec(builder).getObject());
}
}
网友评论