低调人的gravatar头像
低调人 2017-11-24 14:36:01
Spring Boot之Web应用使用Spring-data-jpa多数据源配置

对于数据源的配置可以沿用上例Spring Boot学习(七)之Web应用使用jdbctemplate多数据源配置中DataSourceConfig的实现。

新增对第一数据源的JPA配置,注意两处注释的地方,用于指定数据源对应的Entity实体和Repository定义位置,用@Primary区分主数据源。

package com.xiaojingg;
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;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
/**
 * 筱进GG
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages= { "com.xiaojingg.domain.p" }) //设置Repository所在位置
public class PrimaryConfig {

    @Autowired @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

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

    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource)
                .properties(getVendorProperties(primaryDataSource))
                .packages("com.xiaojingg.domain.p") //设置实体类所在位置
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    @Autowired
    private JpaProperties jpaProperties;

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

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

}

新增对第二数据源的JPA配置,内容与第一数据源类似,具体如下:

package com.xiaojingg;
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;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
/**
 * 筱进GG
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactorySecondary",
        transactionManagerRef="transactionManagerSecondary",
        basePackages= { "com.xiaojingg.domain.s" }) //设置Repository所在位置
public class SecondaryConfig {

    @Autowired @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

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

    @Bean(name = "entityManagerFactorySecondary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondaryDataSource)
                .properties(getVendorProperties(secondaryDataSource))
                .packages("com.xiaojingg.domain.s") //设置实体类所在位置
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
    }

    @Autowired
    private JpaProperties jpaProperties;

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "transactionManagerSecondary")
    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
    }
}

主数据源配置为spring.datasource.primary开头的配置,第二数据源配置为spring.datasource.secondary开头的配置。

package com.xiaojingg;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
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 javax.sql.DataSource;

/**
 * 筱进GG
 */
@Configuration
public class DataSourceConfig {

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

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

}

 

完成了以上配置之后,主数据源的实体和数据访问对象位于:com.xiaojingg.domain.p,次数据源的实体和数据访问接口位于:com.xiaojingg.domain.s

分别在这两个package下创建各自的实体和数据访问接口

  • 主数据源下,创建User实体和对应的Repository接口
package com.xiaojingg.domain.p;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
 * 筱进GG
 */
@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    public User(){}

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

package com.xiaojingg.domain.p;

import org.springframework.data.jpa.repository.JpaRepository;
/**
 * 筱进GG
 */
public interface UserRepository extends JpaRepository<User, Long> {


}
从数据源下,创建Message实体和对应的Repository接口
package com.xiaojingg.domain.s;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
 * 筱进GG
 */
@Entity
public class    Message {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String content;

    public Message(){}

    public Message(String name, String content) {
        this.name = name;
        this.content = content;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

package com.xiaojingg.domain.s;

import org.springframework.data.jpa.repository.JpaRepository;
/**
 * 筱进GG
 */
public interface MessageRepository extends JpaRepository<Message, Long> {


}

最后通过测试用例来验证使用这两个针对不同数据源的配置进行数据操作:

package com.xiaojingg;

import com.xiaojingg.domain.p.User;
import com.xiaojingg.domain.p.UserRepository;
import com.xiaojingg.domain.s.Message;
import com.xiaojingg.domain.s.MessageRepository;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
 * 筱进GG
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootstudyDemo7SpringDataJpaMoreApplicationTests {

   @Autowired
   private UserRepository userRepository;
   @Autowired
   private MessageRepository messageRepository;

   @Before
   public void setUp() {
   }

   @Test
   public void test() throws Exception {

      userRepository.save(new User("aaa", 10));
      userRepository.save(new User("bbb", 20));
      userRepository.save(new User("ccc", 30));
      userRepository.save(new User("ddd", 40));
      userRepository.save(new User("eee", 50));

      Assert.assertEquals(5, userRepository.findAll().size());

      messageRepository.save(new Message("o1", "aaaaaaaaaa"));
      messageRepository.save(new Message("o2", "bbbbbbbbbb"));
      messageRepository.save(new Message("o3", "cccccccccc"));

      Assert.assertEquals(3, messageRepository.findAll().size());

   }

}

运行截图:

Spring Boot之Web应用使用Spring-data-jpa多数据源配置

Spring Boot之Web应用使用Spring-data-jpa多数据源配置

完成了!

源码链接 : Spring Boot学习(七)之Web应用使用Spring-data-jpa多数据源配置 博客源码


打赏

已有2人打赏

已注销用户的gravatar头像 最代码官方的gravatar头像
最近浏览
runandrun  LV2 2020年8月22日
linguo 2020年8月1日
暂无贡献等级
lewiszz  LV2 2020年6月16日
dhb123  LV5 2020年5月19日
已注销用户  LV34 2020年4月1日
yang131221 2020年2月26日
暂无贡献等级
WngYong 2019年12月31日
暂无贡献等级
javaggm  LV13 2019年9月20日
gxcrownclown 2019年8月12日
暂无贡献等级
海问香  LV6 2019年4月25日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友