SpringBoot配置多数据源JPA

titletoclayoutcategoriestagsdate
SpringBoot + Hikari +JPA 多数据源
true
SpringBoot
SpringBoot
SpringBoot
Hikari
JPA
2018/07/19 9:55:23

{{title}}

SpringBoot2.0 Hikari 多数据源 —— JPA

SpringBoot 连接多数据源使用 JPA 查询应用记录.

pom.xml依赖配置

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

注:SpringBoot 2.0默认的数据连接池为Hikari,故不需要添加 Hikari 依赖

多数据源配置

  1. primaryDataSource 配置
package com.learnning.config;

import javax.persistence.EntityManager;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 com.zaxxer.hikari.HikariDataSource;

/**
 * 
 * @ClassName: HikariDataSourceConfig
 * @Description: Hikari 多数据源配置(第一数据源配置)
 * @author time
 * @date 2018/10/29
 * {@link {@link http://blog.didispace.com/springbootmultidatasource/}}
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "primaryEntityManagerFactory", //
		transactionManagerRef = "primaryTransactionManager", //
		basePackages = { "com.learnning.domain.p" }) // 设置Repository所在位置
public class PrimaryConfig {

	@Primary
	@Bean(name = "primaryDataSource")
	@Qualifier(value = "primaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.primary")
	public DataSource primaryDataSource() {
		return DataSourceBuilder.create().type(HikariDataSource.class).build();
	}

	@Primary
	@Bean(name = "primaryEntityManager")
	public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
		return primaryEntityManagerFactory(builder).getObject().createEntityManager();
	}

	@Primary
	@Bean(name = "primaryEntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
		return builder//
				.dataSource(primaryDataSource()) //
				.packages("com.learnning.domain.p")//
				.persistenceUnit("primaryPersistenceUnit")//
				.build();
	}

	@Primary
	@Bean(name = "primaryTransactionManager")
	public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
		return new JpaTransactionManager(primaryEntityManagerFactory(builder).getObject());
	}

}
  1. sencondaryDataSource 配置
package com.learnning.config;

import javax.persistence.EntityManager;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 com.zaxxer.hikari.HikariDataSource;

/**
 * 
 * @ClassName: HikariDataSourceConfig
 * @Description: Hikari 多数据源配置(第一数据源配置)
 * @author time
 * @date 2018/10/29
 * {@link {@link http://blog.didispace.com/springbootmultidatasource/}}
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "secondaryEntityManagerFactory", //
		transactionManagerRef = "secondaryTransactionManager", //
		basePackages = { "com.learnning.domain.s" }) // 设置Repository所在位置
public class SecondaryConfig {

	@Bean(name = "sencondaryDataSource")
	@Qualifier(value = "sencondaryDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.secondary")
	public DataSource sencondaryDataSource() {
		return DataSourceBuilder.create().type(HikariDataSource.class).build();
	}

	@Bean(name = "secondaryEntityManager")
	public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
		return secondaryEntityManagerFactory(builder).getObject().createEntityManager();
	}

	@Bean(name = "secondaryEntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
		return builder//
				.dataSource(sencondaryDataSource()) //
				.packages("com.learnning.domain.s")//
				.persistenceUnit("secondaryPersistenceUnit")//
				.build();
	}

	@Bean(name = "secondaryTransactionManager")
	PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
		return new JpaTransactionManager(secondaryEntityManagerFactory(builder).getObject());
	}

}

JPA 使用多数据源查询

划重点:

  1. JPAentity与table因为有映射关系,所以实体类路径需要映射到对应的DataSource

  2. JPA查询接口最好也根据不同数据源区分开

primary数据源配置

  • primary数据源实体类
package com.learnning.domain.p;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_account")
public class User {

	@Id
	@GeneratedValue
	private Long account_id;

	private String user_name;

	private Integer validity;

	public Long getAccount_id() {
		return account_id;
	}

	public void setAccount_id(Long account_id) {
		this.account_id = account_id;
	}


	public String getUser_name() {
		return user_name;
	}

	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}

	public Integer getValidity() {
		return validity;
	}

	public void setValidity(Integer validity) {
		this.validity = validity;
	}

	@Override
	public String toString() {
		return "{\"account_id\":\"" + account_id + "\",\"user_name\":\"" + user_name + "\",\"validity\":\"" + validity
				+ "\"}";
	}
}
  • primary 数据源Repository
package com.learnning.domain.p.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.learnning.domain.p.User;

public interface UserRepository extends JpaRepository<User, Long> {

	/**
	 * 
	 * @Title: findByAccount_id
	 * @Description: 查询用户 User 信息
	 * 	nativeQuery:指定为原生SQL查询
	 * @param account_id
	 * @return
	 * User
	 */
	/// 模糊匹配
	@Query(value = "select account_id,user_name,validity from t_account where account_id = ?", nativeQuery = true)
	User findByAccount_id(Long account_id);

}

secondary 数据源配置

  • secondary 实体类
package com.learnning.domain.s;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_user")
public class PopUser {

	@Id
	@GeneratedValue
	private Long pop_id;

	private String pop_name;

	private String ip_start;

	private String ip_end;

	private String netmask;

	private String description;

	private String start_num;

	private String end_num;

	private String platform;

	private Integer ipgap;

	private Integer pop_type;

	public Long getPop_id() {
		return pop_id;
	}

	public void setPop_id(Long pop_id) {
		this.pop_id = pop_id;
	}

	public String getPop_name() {
		return pop_name;
	}

	public void setPop_name(String pop_name) {
		this.pop_name = pop_name;
	}

	public String getIp_start() {
		return ip_start;
	}

	public void setIp_start(String ip_start) {
		this.ip_start = ip_start;
	}

	public String getIp_end() {
		return ip_end;
	}

	public void setIp_end(String ip_end) {
		this.ip_end = ip_end;
	}

	public String getNetmask() {
		return netmask;
	}

	public void setNetmask(String netmask) {
		this.netmask = netmask;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getStart_num() {
		return start_num;
	}

	public void setStart_num(String start_num) {
		this.start_num = start_num;
	}

	public String getEnd_num() {
		return end_num;
	}

	public void setEnd_num(String end_num) {
		this.end_num = end_num;
	}

	public String getPlatform() {
		return platform;
	}

	public void setPlatform(String platform) {
		this.platform = platform;
	}

	public Integer getIpgap() {
		return ipgap;
	}

	public void setIpgap(Integer ipgap) {
		this.ipgap = ipgap;
	}

	public Integer getPop_type() {
		return pop_type;
	}

	public void setPop_type(Integer pop_type) {
		this.pop_type = pop_type;
	}

	@Override
	public String toString() {
		return "{\"pop_id\":\"" + pop_id + "\",\"pop_name\":\"" + pop_name + "\",\"ip_start\":\"" + ip_start
				+ "\",\"ip_end\":\"" + ip_end + "\",\"netmask\":\"" + netmask + "\",\"description\":\"" + description
				+ "\",\"start_num\":\"" + start_num + "\",\"end_num\":\"" + end_num + "\",\"platform\":\"" + platform
				+ "\",\"ipgap\":\"" + ipgap + "\",\"pop_type\":\"" + pop_type + "\"}";
	}

}
  • secondary 数据源 Repository
package com.learnning.domain.s.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.learnning.domain.s.PopUser;

public interface PopUserRepository extends JpaRepository<PopUser, Long> {

	@Query(value = "select pop_name,pop_id,ip_start,ip_end,netmask,description,start_num,end_num,platform,ipgap,pop_type from t_user where rownum<= 10", nativeQuery = true)
	List<PopUser> queryPopUserPage1();

}

测试类

@Autowired
private UserRepository userRepository;

@Autowired
private PopUserRepository popUserRepository;

@Test
public void testPrimarySession() {
	User users = userRepository.findByAccount_id(1L);
	System.out.println(users.toString());

	List<PopUser> page = popUserRepository.queryPopUserPage1();
	System.out.println(page.toString());

}

注: SpringBoot官方建议使用构造函数的方式注入依赖,上述测试代码为在测试类中使用.

使用构造函数注入如下:

private UserRepository userRepository;

private PopUserRepository popUserRepository;

@Autowired
public MyErrorController(UserRepository userRepository, PopUserRepository popUserRepository) {
	this.userRepository = userRepository;
	this.popUserRepository = popUserRepository;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值