简介
微服务提倡单服务单数据库;但是,一个微服务连接多个数据库是不可避免的。今天,我将介绍如何使用它 JPA 多数据源。主要使用不同数据库 Repository 接口分别存储在不同的接口中 package,Spring 扫描不同的包,注入不同的数据源来实现多数据源。
创建 jpa-multip-datasource db01和db02数据库分别创建学生表 t_student
CREATE TABLE `t_student` (`id` int(11) NOT NULL AUTO_INCREMENT ,`user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,`sex` int(1) NULL DEFAULT NULL ,`grade` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,PRIMARY KEY (`id`))ENGINE=InnoDBDEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ciAUTO_INCREMENT=1 ROW_FORMAT=DYNAMIC;
教师表 t_teacher
CREATE TABLE `t_teacher` (`id` int(11) NOT NULL AUTO_INCREMENT ,`user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,`sex` int(1) NULL DEFAULT NULL ,`office` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,PRIMARY KEY (`id`))ENGINE=InnoDBDEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ciAUTO_INCREMENT=1 ROW_FORMAT=DYNAMIC;
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.olive</groupId><artifactId>jpa-multip-datasource</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>jpa-multip-datasource</name><url>http://maven.apache.org</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.14</version><relativePath /> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><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-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>
配置两个数据源
第一个主数据源分别是第一个(primary),第二数据源(second),具体配置如下:
# server基本配置: port: 8080# Spring数据库: jpa: show-sql: true database-platform: org.hibernate.dialect.MySQL5InnoDBDialect hibernate: ddl-auto: update datasource: primary: driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/db01?characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true username: root password: root sencond: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/db02?characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true username: root password: root jackson: serialization: indent-output: true
配置数据源
DataSourceConfig 配置
/** * @Description: 数据源配置 */@Configurationpublic class DataSourceConfig { @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") @Primary public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondDataSource") @Qualifier("secondDataSource") @ConfigurationProperties(prefix = "spring.datasource.sencond") public DataSource secondDataSource() { return DataSourceBuilder.create().build(); }}
Config数据源Primary
/** * @Description: 主数据源配置 * @date */@Configuration@EnableTransactionManagement@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary", transactionManagerRef = "transactionManagerPrimary", basePackages = {"com.olive.repository.primary"})public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired private HibernateProperties hibernateProperties; @Autowired private JpaProperties jpaProperties; @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") //primary实体工厂 public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) { return builder.dataSource(primaryDataSource) .properties(getHibernateProperties()) .packages("com.olive.entity.primary") ////换成你自己的实体类的位置 .persistenceUnit("primaryPersistenceUnit") .build(); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } private Map<String, Object> getHibernateProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); }}
SecondConfig 数据源源
/** * @Description: 第二个数据源配置 */@Configuration@EnableTransactionManagement@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactorySecond", transactionManagerRef = "transactionManagerSecond", basePackages = {"com.olive.repository.second"})public class SecondConfig { @Autowired @Qualifier("secondDataSource") private DataSource secondDataSource; @Resource private JpaProperties jpaProperties; @Resource private HibernateProperties hibernateProperties; @Bean(name = "entityManagerSecond") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecond(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecond") //primary实体工厂 public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond (EntityManagerFactoryBuilder builder) { return builder.dataSource(secondDataSource) .properties(getHibernateProperties()) .packages("com.olive.entity.second") ////换成你自己的实体类的位置 .persistenceUnit("secondaryPersistenceUnit") .build(); } @Bean(name = "transactionManagerSecond") public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject()); } private Map<String, Object> getHibernateProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); }}
创建学生和教师的实体类别
Student实体类
package com.olive.entity.primary;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import lombok.Data;@Data@Entity(name="t_student")public class StudentDO implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "user_name") // 若实体属性与表字段名称一致,不需要添加@Column注释 private String name; @Column(name = "sex") private int sex; @Column(name = "grade") private String grade;}
Teacher实体类
package com.olive.entity.second;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import lombok.Data;@Data@Entity(name="t_teacher")public class TeacherDO implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "user_name") // 若实体属性与表字段名称一致,无需添加@Column注释privatete String name;@Column(name = "sex")private int sex;@Column(name = "office")private String office;}
数据库持久类
Studentrepositor
package com.olive.repository.primary;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;import com.olive.entity.primary.StudentDO;@Repositorypublic interface StudentRepository extends JpaRepository<StudentDO, Long> {}
Teacherrepositor
package com.olive.repository.second;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;import com.olive.entity.second.TeacherDO;@Repositorypublic interface TeacherRepository extends JpaRepository<TeacherDO, Long> {}
创建springboot引导类
package com.olive;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class); }}
测试
package com.olive;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import com.olive.entity.primary.StudentDO;import com.olive.entity.second.TeacherDO;import com.olive.repository.primary.StudentRepository;import com.olive.repository.second.TeacherRepository;@SpringBootTestpublic class JpaTest {@AutowiredStudentRepository studentRepository;@AutowiredTeacherRepository teacherRepository;@Testpublic void userSave() {StudentDO studentDO = new StudentDO();studentDO.setName(“BUG弄潮儿”);studentDO.setSex(1);studentDO.setGrade(一年级);studentRepository.save(studentDO);TeacherDO teacherDO = new TeacherDO();teacherDO.setName(Java乐园);teacherDO.setSex(2);teacherDO.setOffice(语文);teacherRepository.save(teacherDO);}}