项目结构
![](https://img-blog.csdnimg.cn/1183a97bc27b486cbed6cf56b067e272.png)
1.依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL 驱动, 注意, 这个需要与 MySQL 版本对应 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
<scope>runtime</scope>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>
2.application.yml
server:
port: 8900 #端口
spring:
datasource:
#主数据源
primary:
url: jdbc:mysql://192.168.64.132:3306/testdb?serverTimezone=GMT&seUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
#从数据源
secondary:
url: jdbc:mysql://192.168.64.132:3307/testdb?serverTimezone=GMT&seUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
jpa:
#主jpa配置
primary:
show-sql: true
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL8Dialect
#从jpa配置
secondary:
show-sql: true
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL8Dialect
3.主数据源配置
package com.xiaoxi.demo.config.primaryconfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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 org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class PrimaryDataSourceConfig {
/**
* 扫描spring.datasource.primary开头的配置信息
*
* @return 数据源配置信息
*/
@Primary
@Bean(name = "primaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
/**
* 取主库数据源对象
*
* @param dataSourceProperties 注入名为primaryDataSourceProperties的bean
* @return 数据源对象
*/
@Primary
@Bean(name = "primaryDataSource")
public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
/**
* 该方法仅在需要使用JdbcTemplate对象时选用
*
* @param dataSource 注入名为primaryDataSource的bean
* @return 数据源JdbcTemplate对象
*/
@Primary
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
4.主实体类创建
package com.xiaoxi.demo.entity.primaryentity;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity // jpa特有,必须加
@Table(name = "t_user")
public class PrimaryTbUserEntity {
@Id //主键id
@GeneratedValue(strategy= GenerationType.IDENTITY)//主键生成策略
@Column(name="id") //数据库字段名
private Integer id;
@Column(name = "uname")
private String uname;
}
5.主repository创建
package com.xiaoxi.demo.dao.primaryrepository;
import com.xiaoxi.demo.entity.primaryentity.PrimaryTbUserEntity;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository("primaryUserRepository")
@Primary
public interface PrimaryUserRepository extends JpaRepository<PrimaryTbUserEntity, Integer> {
}
6.主jpa配置
package com.xiaoxi.demo.config.primaryconfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = PrimaryJpaConfig.REPOSITORY_PACKAGE,
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryJpaConfig {
static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.primaryrepository";
private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.primaryentity";
/**
* 扫描spring.jpa.primary开头的配置信息
*
* @return jpa配置信息
*/
@Primary
@Bean(name = "primaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.primary")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
/**
* 获取主库实体管理工厂对象
*
* @param primaryDataSource 注入名为primaryDataSource的数据源
* @param jpaProperties 注入名为primaryJpaProperties的jpa配置信息
* @param builder 注入EntityManagerFactoryBuilder
* @return 实体管理工厂对象
*/
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(
@Qualifier("primaryDataSource") DataSource primaryDataSource,
@Qualifier("primaryJpaProperties") JpaProperties jpaProperties,
EntityManagerFactoryBuilder builder
) {
return builder
// 设置数据源
.dataSource(primaryDataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages(ENTITY_PACKAGE)
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("primaryPersistenceUnit").build();
}
/**
* 获取实体管理对象
*
* @param factory 注入名为primaryEntityManagerFactory的bean
* @return 实体管理对象
*/
@Primary
@Bean(name = "primaryEntityManager")
public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
/**
* 获取主库事务管理对象
*
* @param factory 注入名为primaryEntityManagerFactory的bean
* @return 事务管理对象
*/
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
}
7.从数据源配置
package com.xiaoxi.demo.config.secondaryconfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class SecondaryDataSourceConfig {
/**
* 扫描spring.datasource.secondary开头的配置信息
*
* @return 数据源配置信息
*/
@Bean(name = "secondaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
/**
* 获取次数据源对象
*
* @param dataSourceProperties 注入名为secondaryDataSourceProperties的bean
* @return 数据源对象
*/
@Bean("secondaryDataSource")
public DataSource dataSource(@Qualifier("secondaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
/**
* 该方法仅在需要使用JdbcTemplate对象时选用
*
* @param dataSource 注入名为secondaryDataSource的bean
* @return 数据源JdbcTemplate对象
*/
@Bean(name = "secondaryJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
8.从jpa配置
package com.xiaoxi.demo.config.secondaryconfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = SecondaryJpaConfig.REPOSITORY_PACKAGE,
entityManagerFactoryRef = "secondaryEntityManagerFactory",
transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryJpaConfig {
static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.secondaryrepository";
private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.secondaryentity";
/**
* 扫描spring.jpa.secondary
*
* @return jpa配置信息
*/
@Bean(name = "secondaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.secondary")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
/**
* 获取次库实体管理工厂对象
*
* @param secondaryDataSource 注入名为secondaryDataSource的数据源
* @param jpaProperties 注入名为secondaryJpaProperties的jpa配置信息
* @param builder 注入EntityManagerFactoryBuilder
* @return 实体管理工厂对象
*/
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("secondaryDataSource") DataSource secondaryDataSource,
@Qualifier("secondaryJpaProperties") JpaProperties jpaProperties,
EntityManagerFactoryBuilder builder
) {
return builder
// 设置数据源
.dataSource(secondaryDataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages(ENTITY_PACKAGE)
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("secondaryPersistenceUnit").build();
}
/**
* 获取实体管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 实体管理对象
*/
@Bean(name = "secondaryEntityManager")
public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
/**
* 获取主库事务管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 事务管理对象
*/
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
}
9.从实体类配置
package com.xiaoxi.demo.entity.secondaryentity;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity // jpa特有,必须加
@Table(name = "t_user")
public class SecondaryTbUserEntity {
@Id //主键id
@GeneratedValue(strategy= GenerationType.IDENTITY)//主键生成策略
@Column(name="id") //数据库字段名
private Integer id;
@Column(name = "uname")
private String name;
}
10.从repository创建
package com.xiaoxi.demo.dao.secondaryrepository;
import com.xiaoxi.demo.entity.secondaryentity.SecondaryTbUserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository("secondaryUserRepository")
public interface SecondaryUserRepository extends JpaRepository<SecondaryTbUserEntity, Integer> {
}
11.从jpa配置
package com.xiaoxi.demo.config.secondaryconfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = SecondaryJpaConfig.REPOSITORY_PACKAGE,
entityManagerFactoryRef = "secondaryEntityManagerFactory",
transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryJpaConfig {
static final String REPOSITORY_PACKAGE = "com.xiaoxi.demo.dao.secondaryrepository";
private static final String ENTITY_PACKAGE = "com.xiaoxi.demo.entity.secondaryentity";
/**
* 扫描spring.jpa.secondary
*
* @return jpa配置信息
*/
@Bean(name = "secondaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.secondary")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
/**
* 获取次库实体管理工厂对象
*
* @param secondaryDataSource 注入名为secondaryDataSource的数据源
* @param jpaProperties 注入名为secondaryJpaProperties的jpa配置信息
* @param builder 注入EntityManagerFactoryBuilder
* @return 实体管理工厂对象
*/
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("secondaryDataSource") DataSource secondaryDataSource,
@Qualifier("secondaryJpaProperties") JpaProperties jpaProperties,
EntityManagerFactoryBuilder builder
) {
return builder
// 设置数据源
.dataSource(secondaryDataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages(ENTITY_PACKAGE)
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("secondaryPersistenceUnit").build();
}
/**
* 获取实体管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 实体管理对象
*/
@Bean(name = "secondaryEntityManager")
public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
/**
* 获取主库事务管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 事务管理对象
*/
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
}
12.测试
package com.xiaoxi.demo.controllerr;
import com.alibaba.fastjson2.JSON;
import com.xiaoxi.demo.dao.primaryrepository.PrimaryUserRepository;
import com.xiaoxi.demo.dao.secondaryrepository.SecondaryUserRepository;
import com.xiaoxi.demo.entity.primaryentity.PrimaryTbUserEntity;
import com.xiaoxi.demo.entity.secondaryentity.SecondaryTbUserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@RestController
public class TestMutiDataSource {
@Autowired
PrimaryUserRepository primaryUserRepository;
@Autowired
@Qualifier("secondaryUserRepository")
SecondaryUserRepository secondaryUserRepository;
@GetMapping("/test")
public String TestMutiDataSource() {
Map<String, String> re = new HashMap<>();
Optional<PrimaryTbUserEntity> byId = primaryUserRepository.findById(1);
if(byId.isPresent()) {
re.put("主库数据", JSON.toJSONString(byId.get()));
}
Optional<SecondaryTbUserEntity> byIdSecondary = secondaryUserRepository.findById(2);
if(byIdSecondary.isPresent()) {
re.put("从库数据", JSON.toJSONString(byIdSecondary.get()));
}
return JSON.toJSONString(re);
}
}
打印:
{
"从库数据": "{\"id\":2,\"name\":\"lisi4\"}",
"主库数据": "{\"id\":1,\"uname\":\"zhang3\"}"
}
总结:
jpa配置多数据源就是配置多个repository,每个 repository对应操作不同的数据源