1 介绍
-
2 示例
2.1 依赖引入
注意:pom不要去改,引入其他druid会报错的!
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>
2.2 自定义配置两个数据库
application.yml
spring:datasource:primary:url: jdbc:mysql://localhost:3306/primary?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driversecondary:url: jdbc:mysql://localhost:3306/second?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverjpa:database: mysqlgenerate-ddl: trueshow-sql: truehibernate:ddl-auto: updatenaming:physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
2.3 配置默认的数据库源
```java package com.hikktn.config;
import com.alibaba.druid.pool.DruidDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component;
import javax.sql.DataSource; import java.sql.SQLException;
@Component @Configuration public class DataSourceConfig {
private Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);@Value("${spring.datasource.primary.url}")private String dbUrl1;@Value("${spring.datasource.primary.username}")private String username1;@Value("${spring.datasource.primary.password}")private String password1;@Value("${spring.datasource.secondary.username}")private String username2;@Value("${spring.datasource.secondary.password}")private String password2;@Value("${spring.datasource.secondary.url}")private String dbUrl2;@Value("${spring.datasource.secondary.driver-class-name}")private String driverClassName;@Value("5")private int initialSize;@Value("5")private int minIdle;@Value("20")private int maxActive;@Value("60000")private int maxWait;/*** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒*/@Value("60000")private int timeBetweenEvictionRunsMillis;/*** 配置一个连接在池中最小生存的时间,单位是毫秒*/@Value("300000")private int minEvictableIdleTimeMillis;@Value("SELECT 1 FROM DUAL")private String validationQuery;@Value("true")private boolean testWhileIdle;@Value("false")private boolean testOnBorrow;@Value("false")private boolean testOnReturn;/*** 打开PSCache,并且指定每个连接上PSCache的大小*/@Value("true")private boolean poolPreparedStatements;@Value("20")private int maxPoolPreparedStatementPerConnectionSize;/*** 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙*/@Value("stat,wall,log4j")private String filters;/*** 通过connectProperties属性来打开mergeSql功能;慢SQL记录*/@Value("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500")private String connectionProperties;@Bean(name = "primaryDataSource")@Qualifier("primaryDataSource")public DataSource dataSource() {return getDruidDataSource(username1, password1, dbUrl1);}@Bean(name = "secondDataSource")@Qualifier("secondDataSource")@Primarypublic DataSource secondaryDataSource() {return getDruidDataSource(username2, password2, dbUrl2);}private DruidDataSource getDruidDataSource(String username, String password, String url) {DruidDataSource datasource = new DruidDataSource();datasource.setUrl(url);datasource.setUsername(username);datasource.setPassword(password);datasource.setDriverClassName(driverClassName);//configurationdatasource.setInitialSize(initialSize);datasource.setMinIdle(minIdle);datasource.setMaxActive(maxActive);datasource.setMaxWait(maxWait);datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);datasource.setValidationQuery(validationQuery);datasource.setTestWhileIdle(testWhileIdle);datasource.setTestOnBorrow(testOnBorrow);datasource.setTestOnReturn(testOnReturn);datasource.setPoolPreparedStatements(poolPreparedStatements);datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);try {datasource.setFilters(filters);} catch (SQLException e) {logger.error("druid configuration initialization filter : {0}", e);}datasource.setConnectionProperties(connectionProperties);return datasource;}
}
<a name="pIgz2"></a>## 2.4 JPA配置主数据库```javapackage com.hikktn.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.autoconfigure.domain.EntityScan;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.core.env.Environment;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.EntityManager;import javax.sql.DataSource;import java.util.Map;@Configuration@EnableTransactionManagement@EntityScan(basePackages = "com.hikktn.domain.primary")@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary",transactionManagerRef = "transactionManagerPrimary",basePackages = {"com.hikktn.dao.primary"})public class PrimaryConfig {@Autowired@Qualifier("primaryDataSource")private DataSource primaryDataSource;@Autowiredprivate JpaProperties jpaProperties;@Autowiredprivate HibernateProperties hibernateProperties;private Map<String, Object> getVendorProperties() {return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());}@Primary@Bean(name = "entityManagerPrimary")public EntityManager entityManager(EntityManagerFactoryBuilder builder) {return entityManagerFactoryPrimary(builder).getObject().createEntityManager();}@Primary@Bean(name = "entityManagerFactoryPrimary")public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {return builder.dataSource(primaryDataSource).properties(getVendorProperties()).packages("com.hikktn.domain.primary").persistenceUnit("primaryPersistenceUnit").build();}@Primary@Bean(name = "transactionManagerPrimary")public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());}}
2.5 JPA配置副数据库
package com.hikktn.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.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;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.annotation.Resource;import javax.persistence.EntityManager;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;@Configuration@EnableTransactionManagement@EnableJpaRepositories(//实体管理entityManagerFactoryRef="entityManagerFactorySecond",//事务管理transactionManagerRef="transactionManagerSecond",//实体扫描,设置Repository所在位置basePackages= { "com.hikktn.dao.second" })public class SecondConfig {@Autowired@Qualifier("secondDataSource")private DataSource secondDataSource;@Autowiredprivate JpaProperties jpaProperties;@Autowiredprivate HibernateProperties hibernateProperties;private Map<String, Object> getVendorProperties() {return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());}@Bean(name = "entityManagerSecond")public EntityManager entityManager(EntityManagerFactoryBuilder builder) {return entityManagerFactorySecond(builder).getObject().createEntityManager();}@Bean(name = "entityManagerFactorySecond")public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond (EntityManagerFactoryBuilder builder) {return builder.dataSource(secondDataSource).properties(getVendorProperties()).packages("com.hikktn.domain.second").persistenceUnit("secondPersistenceUnit").build();}@Bean(name = "transactionManagerSecond")PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());}}
2.6 主数据库Bean
package com.hikktn.domain.primary;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import javax.persistence.*;import java.io.Serializable;@Data@Entity@NoArgsConstructor@AllArgsConstructor@Table(name = "t_user")public class UserPrimaryEntity implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)Long id;/*** 名称*/String name;/*** 性别*/String sex;}
2.7 副数据库Bean
package com.hikktn.domain.second;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import javax.persistence.*;import java.io.Serializable;@Data@Entity@NoArgsConstructor@AllArgsConstructor@Table(name = "t_user")public class UserSecondEntity implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)Long id;/*** 名称*/String name;/*** 性别*/String sex;}
2.8 DAO层
package com.hikktn.dao.primary;import com.hikktn.domain.primary.UserPrimaryEntity;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface UserPrimaryRepository extends JpaRepository<UserPrimaryEntity, Long> {}
package com.hikktn.dao.second;import com.hikktn.domain.second.UserSecondEntity;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface UserSecondRepository extends JpaRepository<UserSecondEntity, Long> {}
2.9 启动类
package com.hikktn;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
2.10 测试
import com.hikktn.Application;import com.hikktn.dao.primary.UserPrimaryRepository;import com.hikktn.dao.second.UserSecondRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTest(classes = Application.class)public class SpringbootJapDatasourceApplicationTests {@Autowiredprivate UserPrimaryRepository userPrimaryRepository;@Autowiredprivate UserSecondRepository userSecondRepository;@Testpublic void contextLoads() {System.out.println(userPrimaryRepository.findAll());System.out.println(userSecondRepository.findAll());}}
- 数据库里的数据

- 结果
Hibernate: select userprimar0_.id as id1_0_, userprimar0_.name as name2_0_, userprimar0_.sex as sex3_0_ from t_user userprimar0_[UserPrimaryEntity(id=1, name=zhansan, sex=男), UserPrimaryEntity(id=2, name=tom, sex=男)]2021-08-31 23:44:44.991 INFO 16516 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactoryHibernate: select usersecond0_.id as id1_0_, usersecond0_.name as name2_0_, usersecond0_.sex as sex3_0_ from t_user usersecond0_[UserSecondEntity(id=1, name=kitty, sex=女)]
