由于现在很多系统都不在使用单一数据库,所以想试下springboot jpa多数据源配置,网上也有很多这方便的文章,可能是版本不一致,存在这各种问题,始终无法成功运行,后经过反复尝试,最后终于成功运行,这里做下记录:
springboot 版本:2.2.2.RELEASE
数据库:mysql 5.7
开发工具:idea 2019.2
1、首先要有多个数据库,我这里创建了2个数据库demo、demo2
2、创建项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、application.yml
spring:
datasource:
ds1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 1234
ds2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/demo2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 1234
jpa:
hibernate:
ddl-auto: update
open-in-view: true
properties:
hibernate:
physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
dialect: org.hibernate.dialect.MySQL57Dialect
format_sql: true
hbm2ddl:
auto: update
show-sql: true
database: mysql
配置说明:
springboot默认使用的HikariPool数据源,数据源配置应使用jdbc-url,而不是常用的url。单个数据源时使用的spring.jpa.hibernate下的配置,而使用多数据源时则使用的是spring.jpa.hibernate.properties下的配置,具体配置网上有很多数据,在此就不多做说明,不清楚的可以网上查一下。这里就提一下physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
这两个配置是创建表时表字段使用下划线形式,而不是驼峰形式,若不配置,表字段和实体属性一致。
3、实体类,此处创建两个实体类,分别对应demo、demo2两个数据库
Person类
@Entity
@Table(name = "d_person")
public class Person implements Serializable {
private static final long serialVersionUID = 580119470723651341L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String personNo;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPersonNo() {
return personNo;
}
public void setPersonNo(String personNo) {
this.personNo = personNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Student类
@Entity
@Table(name = "d_student")
public class Student implements Serializable {
private static final long serialVersionUID = 7993941906610435818L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String studentNo;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStudentNo() {
return studentNo;
}
public void setStudentNo(String studentNo) {
this.studentNo = studentNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4、Repository类
@Repository
public interface PersonRepository extends BaseRepository<Person,Long> {
}
@Repository
public interface StudentRepository extends BaseRepository<Student,Long> {
}
这里的BaseRepository是我自己定义的接口,主要继承了Repository接口
5、配置类
DataSourceConfigDs1和DataSourceConfigDs2分别对应demo、demo2
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryDs1",//配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerDs1", //配置 事物管理器 transactionManager
basePackages = {"com.example.demo1.repository.ds1"}
)
public class DataSourceConfigDs1 {
@Bean(name = "ds1")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSource dataSourceDs1(){
return DataSourceBuilder.create().build();
}
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerDs1")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean("entityManagerFactoryDs1")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceDs1())
.properties(jpaProperties.getProperties())
.packages("com.example.demo1.repository.ds1")
//持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
.persistenceUnit("persistenceUnitDs1")
.build();
}
@Bean("transactionManagerDs1")
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryDs2",//配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerDs2", //配置 事物管理器 transactionManager
basePackages = {"com.example.demo1.repository.ds2"}
)
public class DataSourceConfigDs2 {
@Bean(name = "ds2")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSource dataSourceDs2(){
return DataSourceBuilder.create().build();
}
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerDs2")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean(value = "entityManagerFactoryDs2")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceDs2())
.properties(jpaProperties.getProperties())
.packages("com.example.demo1.repository.ds2")
//持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
.persistenceUnit("persistenceUnitDs2")
.build();
}
@Bean("transactionManagerDs2")
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
}
}
配置多数据源时需要指定主数据源,使用@Primary即可。basePackages 为Reporitory类路径,对应的实体类应该在Repository类路径下。
项目启动后可以看到控制台有sql打印:
image.png
image.png
通过navicat工具查看:
image.png
表结构:
image.png
image.png
由上图可以看出字段为下划线格式
到此整个springboot jpa多数源的配置过程就完成了。
代码github:https://github.com/panli1988/demo1/tree/master/src/main/java/com/example/demo1
网友评论