前面提到过,JPA是ORM架构的规范,通过JPA也可以很好的简化对数据库的操作。
下面开始基于springboot整合jap的多数据源。
github:https://github.com/fengqing11/datasources-jpa
完整项目截图:
创建数据库:
创建项目,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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>xyz.fengqing11</groupId>
<artifactId>datasources-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>datasources-jpa</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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</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>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置数据源:
在配置数据源的基础上配置jpa
# 数据源1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.jdbc-url=jdbc:mysql:///jdbctemplate?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.one.username=root
spring.datasource.one.password=root
# 数据源2
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.jdbc-url=jdbc:mysql:///jbdctemplate2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.two.username=root
spring.datasource.two.password=root
spring.jpa.properties.database=mysql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.show-sql=true
创建实体类:
package xyz.fengqing11.datasourcesjpa.pojo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String gender;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
创建数据源配置类:
@Primary注解用于指定主数据链,有优先考虑权
package xyz.fengqing11.datasourcesjpa.config;
import com.alibaba.druid.pool.DruidAbstractDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.beans.ConstructorProperties;
@Configuration
public class DataSourcesConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.one")
DataSource dsOne(){
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.two")
DataSource dsTwo(){
return DataSourceBuilder.create().build();
}
}
常见JPA配置类:
这里有两个配置类,对应两个数据源。
package xyz.fengqing11.datasourcesjpa.config;
import org.springframework.beans.factory.annotation.Autowired;
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.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.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "xyz.fengqing11.datasourcesjpa.dao1",
entityManagerFactoryRef = "entityManagerFactoryBeanOne",
transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {
@Resource(name = "dsOne")
DataSource dsOne;
@Autowired
JpaProperties jpaProperties;
@Bean
@Primary
LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(
EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsOne)
.properties(jpaProperties.getProperties())
.packages("xyz.fengqing11.datasourcesjpa.pojo")
.persistenceUnit("pu1")
.build();
}
@Bean
@Primary
PlatformTransactionManager platformTransactionManagerOne(
EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryOne =
entityManagerFactoryBeanOne(builder);
return new JpaTransactionManager(factoryOne.getObject());
}
}
仔细观察还是能看到区别的,JpaConfig2少了一个@Primary注解
package xyz.fengqing11.datasourcesjpa.config;
import org.springframework.beans.factory.annotation.Autowired;
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.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.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "xyz.fengqing11.datasourcesjpa.dao2",
entityManagerFactoryRef = "entityManagerFactoryBeanTwo",
transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {
@Resource(name = "dsTwo")
DataSource dsTwo;
@Autowired
JpaProperties jpaProperties;
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(
EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsTwo)
.properties(jpaProperties.getProperties())
.packages("xyz.fengqing11.datasourcesjpa.pojo")
.persistenceUnit("pu2")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerTwo(
EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryTwo =
entityManagerFactoryBeanTwo(builder);
return new JpaTransactionManager(factoryTwo.getObject());
}
}
创建Repository:
内容如下:
package xyz.fengqing11.datasourcesjpa.dao1;
import org.springframework.data.jpa.repository.JpaRepository;
import xyz.fengqing11.datasourcesjpa.pojo.User;
public interface UserDao1 extends JpaRepository<User, Integer> {
}
除了类名,没啥区别
package xyz.fengqing11.datasourcesjpa.dao2;
import org.springframework.data.jpa.repository.JpaRepository;
import xyz.fengqing11.datasourcesjpa.pojo.User;
public interface UserDao2 extends JpaRepository<User, Integer> {
}
创建Controller:
方便起见,省略了service层。
该类分别向两张表中各插入了一条记录。
package xyz.fengqing11.datasourcesjpa.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import xyz.fengqing11.datasourcesjpa.dao1.UserDao1;
import xyz.fengqing11.datasourcesjpa.dao2.UserDao2;
import xyz.fengqing11.datasourcesjpa.pojo.User;
@RestController
public class UserController {
@Autowired
UserDao1 userDao1;
@Autowired
UserDao2 userDao2;
@GetMapping("/test")
public void test(){
User u1 = new User();
u1.setAge(55);
u1.setGender("男");
u1.setName("氨基酸诋毁");
userDao1.save(u1);
User u2 = new User();
u2.setAge(44);
u2.setGender("女");
u2.setName("爱上丢眼");
userDao2.save(u2);
}
}
运行结果:
-end-