springboot jpa 多数据源 的案例
一、先来个application.properties文件
spring.profiles.active=@package.environment@
spring.mvc.favicon.enable=false
#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
#热部署文件,页面不产生缓存,及时更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
#server.port=8080
#server.session.timeout=28800
server.servlet.session.timeout=3600s
#server.servlet.context-path=/shiro
#spring.main.allow-bean-definition-overriding=true
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tweb?useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
#spring.datasource.username=root
#spring.datasource.password=root__
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto:create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database=mysql
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.primary.jdbc-url=jdbc:mysql://127.0.0.1:3306/test01?useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.primary.username=root
spring.datasource.primary.password=root__
spring.datasource.second.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.second.jdbc-url=jdbc:mysql://127.0.0.1:3306/test02?useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.second.username=root
spring.datasource.second.password=root__
先说第一个坑,默认的jpa用的是spring.datasource.下,且JdbcURL的连接key为url。
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tweb?useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
#spring.datasource.username=root
#spring.datasource.password=root__
而自定义数据源的为spring.datasource.xxxx.下(xxxx为自定义数据源标识),且JdbcURL的连接key为jdbc-url。
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.primary.jdbc-url=jdbc:mysql://127.0.0.1:3306/test01?useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.primary.username=root
spring.datasource.primary.password=root__
二、再来个pom.xml引入依赖
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.imddysc</groupId>
<artifactId>springbootmultidatasources</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springbootmultidatasources</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compilet.target>1.8</maven.compilet.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<!--lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- <scope>test</scope> -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入 -->
<scope>true</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- spring-boot-starter-jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<!-- 文件上传解析器 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<finalName>springbootmultidatasources</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>application*.properties</exclude>
<exclude>**/*.woff</exclude>
<exclude>**/*.woff2</exclude>
<exclude>**/*.ttf</exclude>
<exclude>**/*.ico</exclude>
<exclude>**/*.eot</exclude>
<exclude>**/*.svg</exclude>
<exclude>**/*.otf</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application.properties</include>
<include>application-${package.environment}.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.woff</include>
<include>**/*.woff2</include>
<include>**/*.ttf</include>
<include>**/*.ico</include>
<include>**/*.eot</include>
<include>**/*.svg</include>
<include>**/*.otf</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<!--fork : 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
三、创建数据库和数据
CREATE DATABASE test01 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE test02 DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
在不同数据库下建不同的表
test01库下建student表
CREATE TABLE `student` (
`id` int NOT NULL AUTO_INCREMENT COMMENT "ID",
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "姓名",
`age` int NOT NULL COMMENT "年龄",
`grade` int NOT NULL COMMENT "年级",
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
test02库下建teacher表
CREATE TABLE `teacher` (
`id` int NOT NULL AUTO_INCREMENT COMMENT "ID",
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "姓名",
`age` int NOT NULL COMMENT "年龄",
`course` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "课程",
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
四、编写多数据源的配置文件
多数据源 DataSourceConfig.java 文件编写
package com.imddysc.springbootmultidatasources.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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;
@Configuration
public class DataSourceConfig2 {
@Primary
@Bean(name="primaryDataSource")
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix="spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name="secondDataSource")
@Qualifier("secondDataSource")
@ConfigurationProperties(prefix="spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
多数据源第1个标识数据的jpa配置文件编写(PrimaryJpaConfig.java)
package com.imddysc.springbootmultidatasources.config;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {
"com.imddysc.springbootmultidatasources.repository" }) //设置dao(repo)所在位置
public class PrimaryJpaConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Autowired
private JpaProperties jpaProperties;
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)
.properties(jpaProperties.getProperties())
.packages("com.imddysc.springbootmultidatasources.entity") // 设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "transactionManagerPrimary")
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
多数据源第2个标识数据的jpa配置文件编写(SecondJpaConfig.java)
package com.imddysc.springbootmultidatasources.config;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecond",
transactionManagerRef = "transactionManagerSecond",
basePackages = {
"com.imddysc.springbootmultidatasources.secondrepository" }) //设置dao(repo)所在位置
public class SecondJpaConfig {
@Autowired
@Qualifier("secondDataSource")
private DataSource secondDataSource;
@Autowired
private JpaProperties jpaProperties;
@Bean(name = "entityManagerFactorySecond")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondDataSource)
.properties(jpaProperties.getProperties())
.packages("com.imddysc.springbootmultidatasources.secondentity") // 设置实体类所在位置
.persistenceUnit("secondPersistenceUnit")
.build();
}
@Bean(name = "entityManagerSecond")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Bean(name = "transactionManagerSecond")
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
多数据源是第一个,后2个事多Jpa绑定不同数据源的配置。需要注意的是第一个jpa有@primary注解
还有就是多JPA配置中有不同JPA指定相应的entity的实体包和对应repository包的位置。
五、编写对应的entity和repository
entity (Student.java)
package com.imddysc.springbootmultidatasources.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name="student")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer age;
private Integer grade;
}
repository(StudentRepository.java)
package com.imddysc.springbootmultidatasources.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.imddysc.springbootmultidatasources.entity.Student;
public interface StudentRepository extends JpaRepository<Student, Integer> {
}
entity (thacher.java)
package com.imddysc.springbootmultidatasources.secondentity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name="teacher")
public class Teacher {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer age;
private String course;
}
repository(TeacherRepository.java)
package com.imddysc.springbootmultidatasources.secondrepository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.imddysc.springbootmultidatasources.secondentity.Teacher;
public interface TeacherRepository extends JpaRepository<Teacher, Integer>{
}
六、编写测试Controller
package com.imddysc.springbootmultidatasources.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.imddysc.springbootmultidatasources.entity.Student;
import com.imddysc.springbootmultidatasources.repository.StudentRepository;
@Controller
@RequestMapping("/t1")
public class T1Controller {
@Autowired
private StudentRepository studentRepository;
@ResponseBody
@RequestMapping("/getAll")
public List<Student> getAll() {
return studentRepository.findAll();
}
}
package com.imddysc.springbootmultidatasources.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.imddysc.springbootmultidatasources.secondentity.Teacher;
import com.imddysc.springbootmultidatasources.secondrepository.TeacherRepository;
@Controller
@RequestMapping("/t2")
public class T2Controller {
@Autowired
private TeacherRepository teacherRepository;
@ResponseBody
@RequestMapping("/getAll")
public List<Teacher> getAll() {
return teacherRepository.findAll();
}
}
结果:
http://127.0.0.1:8080/t1/getAll
[{"id":1,"name":"代同学","age":14,"grade":7},{"id":2,"name":"李同学","age":13,"grade":6},{"id":3,"name":"张三","age":15,"grade":8},{"id":4,"name":"王五","age":14,"grade":6},{"id":5,"name":"马力","age":13,"grade":5}]
http://127.0.0.1:8080/t2/getAll
[{"id":1,"name":"陈老师","age":33,"course":"数学"},{"id":2,"name":"蒋老师","age":32,"course":"英语"},{"id":3,"name":"黄飞","age":40,"course":"计算机"}]
对应源码地址: https://gitee.com/lenglingx/springbootjpamultidatasources