springboot+jpa 配置多源数据库

7 篇文章 0 订阅
3 篇文章 0 订阅

前言

公司项目的一个接口需要调用不同数据库,可惜不会配置。单个数据源的还挺好弄得,但是多个数据源就需要手动配置,在网上看了好多博客,花了3天时间,出了好多错最后终于弄出来了,现在分享一下。
个人建议不要再自己项目上改,容易出错,而且需要按照某个版本的博客代码建立一个小demo,跑通了再适当修改,不然容易错上加错,浪费时间
另外这个数据源配置有点死,不是动态配置的,每个数据源需要建一个配置类,有点麻烦

配置文件

application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.jdbc-url=jdbc:mysql://xxxx:3306/xxxx?useSSL=false&characterEncoding=UTF-8&useUnicode=true
spring.datasource.username=xxxxx
spring.datasource.password=xxxxxx
#other
spring.datasource.other.driver-class-name=org.postgresql.Driver
spring.datasource.other.jdbc-url=jdbc:postgresql://123.56.xxx.xxx:3921/kps_development
spring.datasource.other.username=xxxx
spring.datasource.other.password=xxxxx
# third
spring.datasource.third.jdbc-url=jdbc:mysql://47.95.xxx.xxx:8066/basedb?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true
spring.datasource.third.username=xxxx
spring.datasource.third.password=xxxxxxxx
spring.datasource.third.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.hibernate.ddl-auto=none
#spring.jpa.open-in-view=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.max_fetch_depth=1
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.hbm2ddl=update
#spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jackson.serialization.fail-on-empty-beans=false

server.port=8081

配置类

DataSourceConfig

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;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {
    @Bean(name="dataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }

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

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

PrimaryDataSourceConfig

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;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages={"com.star.dao.mysql"})    //注意各个数据源需要映射不同的包
public class PrimaryDataSourceConfig {
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Autowired
    private JpaProperties jpaProperties;

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

    @Primary
    @Bean(name="entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(dataSource)
                .properties(getProperties())
                .packages("com.star.bean.mysql")    //对应实体类
                .persistenceUnit("primaryPersistentUnit")
                .build();
    }

    public Map<String, String> getProperties(){
        Map<String, String> map = jpaProperties.getProperties();
        return map;
    }

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

OtherDataSourceConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryOther",
        transactionManagerRef="transactionManagerOther",
        basePackages={"com.star.dao.postgresql"})
public class OtherDataSourceConfig {

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

    @Autowired
    private JpaProperties jpaProperties;

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

    @Bean(name="entityManagerFactoryOther")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(otherDataSource)
                .properties(getProperties())
                .packages("com.star.bean.postgresql")
                .persistenceUnit("otherPersistentUnit")
                .build();
    }

    public Map<String, String> getProperties(){
        Map<String, String> map = jpaProperties.getProperties();
        return map;
    }

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

ThirdDataSourceConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryThird",
        transactionManagerRef="transactionManagerThird",
        basePackages={"com.star.dao.mysql2"})
public class ThirdDataSourceConfig {
    @Autowired
    @Qualifier("thirdDataSource")
    private DataSource thirdDataSource;

    @Autowired
    private JpaProperties jpaProperties;

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

    @Bean(name="entityManagerFactoryThird")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(thirdDataSource)
                .properties(getProperties())
                .packages("com.star.bean.mysql")
                .persistenceUnit("thirdPersistentUnit")
                .build();
    }

    public Map<String, String> getProperties(){
        Map<String, String> map = jpaProperties.getProperties();
        return map;
    }

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

这里三个数据源的配置几乎一样,只是主数据源多了@Primary。另外就是getProperties()这里需要注意一下,很多版本这里设置不一样,容易出错,我的就是这里报错“字段找不到”,其实实体映射是对的,但是这里配置错了,一直报这样的错误。

测试

dao

public interface BusinessIndexRepository extends JpaRepository<BusinessIndex,Long> {
}

sevice

@Service
public class BusinessIndexService {
    @Autowired
    BusinessIndexRepository businessIndexRepository;

    public BusinessIndex findById(Long id){
        BusinessIndex businessIndex = businessIndexRepository.findById(id).orElse(null);
        return businessIndex;
    }
}

controller

@Slf4j
@RestController
@RequestMapping("/business")
public class BusinessIndexController {
    @Autowired
    BusinessIndexService businessIndexService;

    @RequestMapping("/message")
    public String findBusinessIndex(Long id){
        BusinessIndex business = businessIndexService.findById(id);
        return business.toString();
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值