spring-data-jpa + Alibaba Druid多数据源案例
很多情况下,应用需要连接多个数据库,基于此场景,我介绍如何使用spring-data-jpa + Alibaba Druid配置多数据源。
⚠️
代码量有点大,请耐心
假设一个场景
数据库 | 表 | 服务器IP | 占用端口 |
---|---|---|---|
test | orders(订单表) | 192.168.10.31 | 3306 |
demo | detail(详情表) | 192.168.10.32 | 3306 |
train | users(用户表) | 192.168.10.33 | 3306 |
pom.xml引入
xml
<!--连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!--spring data jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
application.yaml配置
yaml
server:
port: 8080
spring:
datasource:
ds1:
url: jdbc:mysql://192.168.10.31:3306/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
ds2:
url: jdbc:mysql://192.168.10.33:3306/train
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
ds3:
url: jdbc:mysql://192.168.10.32:3306/demo
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
DataSource配置
为了让spring-data-jpa分别使用这三个库,那么我们需要配置3个datasource
java
package cn.train.springdruid.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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 javax.sql.DataSource;
/**
* 多数据源配置
* */
@Configuration
public class DataSourcesConfig {
@Bean(name = {"ds1"})
@Primary
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSource ds1() {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}
@Bean(name = {"ds2"})
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSource ds2() {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}
@Bean(name = {"ds3"})
@ConfigurationProperties(prefix = "spring.datasource.ds3")
public DataSource ds3() {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}
}
JPA配置
接下来针对每个datasource做单独的JPA配置
ds1的JPA配置
java
package cn.train.springdruid.config.datasource;
import org.springframework.beans.factory.annotation.Qualifier;
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.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration(value = "ds1JPAConfig")
@EnableJpaRepositories(
basePackages = "cn.train.springdruid.repositories.ds1",//repository包位置
entityManagerFactoryRef = "ds1EntityManagerFactory",
transactionManagerRef = "ds1TransactionManager"
)
public class Ds1JPAConfig {
@Bean(name = {"ds1TransactionManager"})
public PlatformTransactionManager ds1TransactionManager(
@Qualifier("ds1EntityManagerFactory") EntityManagerFactory emf){
return new JpaTransactionManager(emf);
}
@Bean(name = {"ds1EntityManagerFactory"})
@Primary
public LocalContainerEntityManagerFactoryBean ds1EntityManagerFactory(
@Qualifier(value = "ds1") DataSource dataSource,
JpaVendorAdapter vendorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds1");// entity包位置
entityManagerFactoryBean.setJpaProperties(
new Properties(){{
put("hibernate.hbm2ddl.auto", "update");
put("hibernate.show_sql", "true");
put("hibernate.format_sql", "true");
}}
);
return entityManagerFactoryBean;
}
}
ds2的JPA配置
java
package cn.train.springdruid.config.datasource;
import org.springframework.beans.factory.annotation.Qualifier;
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.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration(value = "ds2JPAConfig")
@EnableJpaRepositories(
basePackages = "cn.train.springdruid.repositories.ds2",//repository包位置
entityManagerFactoryRef = "ds2EntityManagerFactory",
transactionManagerRef = "ds2TransactionManager"
)
public class Ds2JPAConfig {
@Bean(name = {"ds2TransactionManager"})
public PlatformTransactionManager ds2TransactionManager(
@Qualifier("ds2EntityManagerFactory") EntityManagerFactory emf){
return new JpaTransactionManager(emf);
}
@Bean(name = {"ds2EntityManagerFactory"})
public LocalContainerEntityManagerFactoryBean ds2EntityManagerFactory(
@Qualifier(value = "ds2") DataSource dataSource,
JpaVendorAdapter vendorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds2");// entity包位置
entityManagerFactoryBean.setJpaProperties(
new Properties(){{
put("hibernate.hbm2ddl.auto", "update");
put("hibernate.show_sql", "true");
put("hibernate.format_sql", "true");
}}
);
return entityManagerFactoryBean;
}
}
ds3的JPA配置
java
package cn.train.springdruid.config.datasource;
import org.springframework.beans.factory.annotation.Qualifier;
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.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration(value = "ds3JPAConfig")
@EnableJpaRepositories(
basePackages = "cn.train.springdruid.repositories.ds3",//repository包位置
entityManagerFactoryRef = "ds3EntityManagerFactory",
transactionManagerRef = "ds3TransactionManager"
)
public class Ds3JPAConfig {
@Bean(name = {"ds3TransactionManager"})
public PlatformTransactionManager ds3TransactionManager(
@Qualifier("ds3EntityManagerFactory") EntityManagerFactory emf){
return new JpaTransactionManager(emf);
}
@Bean(name = {"ds3EntityManagerFactory"})
public LocalContainerEntityManagerFactoryBean ds3EntityManagerFactory(
@Qualifier(value = "ds3") DataSource dataSource,
JpaVendorAdapter vendorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds3");// entity包位置
entityManagerFactoryBean.setJpaProperties(
new Properties(){{
put("hibernate.hbm2ddl.auto", "update");
put("hibernate.show_sql", "true");
put("hibernate.format_sql", "true");
}}
);
return entityManagerFactoryBean;
}
}
ds1的repository包为:cn.train.springdruid.repositories.ds1,其中是OrderRepository
java
import cn.train.springdruid.entities.ds1.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository(value = "orderRepository")
public interface OrderRepository extends JpaRepository<Order, Long> {
}
ds2的repository包为:cn.train.springdruid.repositories.ds2,其中是UserRepository
java
package cn.train.springdruid.repositories.ds2;
import cn.train.springdruid.entities.ds2.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository(value = "userRepository")
public interface UserRepository extends JpaRepository<User, Long> {
}
ds3的repository包为:cn.train.springdruid.repositories.ds3,其中是DetailRepository
java
package cn.train.springdruid.repositories.ds3;
import cn.train.springdruid.entities.ds3.Detail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository(value = "detailRepository")
public interface DetailRepository extends JpaRepository<Detail, Long> {
}
entity
ds1的entity包为:cn.train.springdruid.entities.ds1,其中是Order
java
package cn.train.springdruid.entities.ds1;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "order_name")
private String name;
@Column(name = "order_price")
private Integer price;
}
ds2的entity包为:cn.train.springdruid.entities.ds2,其中是:User
java
package cn.train.springdruid.entities.ds2;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_name")
private String name;
@Column(name = "user_age")
private Integer age;
}
ds3的entity包为:cn.train.springdruid.entities.ds3,其中是:Detail
java
package cn.train.springdruid.entities.ds3;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "detail")
public class Detail {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@Column(name = "description")
private String description;
}
由此,就是整个多数据源配置与管理的全部核心代码