zoukankan      html  css  js  c++  java
  • Spring Boot——SpringBoot2+JPA+druid配置多数据源

    开发环境

    • SpringBoot:2.2.1RELEASE
    • druid:1.1.20
    • JPA:2.2.1RELEASE
    • maven:3.5.0
    • java:1.8
    • MySQL:8.0.12

    步骤

    • pom.xml配置如下(只列出和文章有关的pom配置)
      • <?xml version="1.0" encoding="UTF-8"?>
        <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>
        
            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.2.1.RELEASE</version>
                <relativePath/> <!-- lookup parent from repository -->
            </parent>
            <groupId>superviserServer</groupId>
            <artifactId>com.test.superviser.server</artifactId>
            <version>1.0-SNAPSHOT</version>
        
            <name>superviserServer</name>
            <description>SuperviserServer Service of Test, Inc.</description>
            <properties>
                <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <java.version>1.8</java.version>
                <resource.delimiter>@</resource.delimiter>
                <spring-boot-starter.version>2.2.1.RELEASE</spring-boot-starter.version>
            </properties>
        <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot-starter.version}</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot-starter.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>${spring-boot-starter.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.20</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.12</version> <exclusions> <exclusion> <artifactId>protobuf-java</artifactId> <groupId>com.google.protobuf</groupId> </exclusion> </exclusions> </dependency> </dependencies> </project>
    • application.yml文件配置如下
      • spring:
          datasource:
            driverClassName: com.mysql.cj.jdbc.Driver
        
            # 使用 alibaba druid 连接池、监控
            type: com.alibaba.druid.pool.DruidDataSource
            druid:
              primary :
                url: jdbc:mysql://localhost:3306/XXXXX?useUnicode=true&CharSet=utf8mb4&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&autoReconnectForPools=true&rewriteBatchedStatements=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
                username: XXXX
                password: XXXX
              secondary :
                url: jdbc:mysql://localhost:3306/XXXXXXX?useUnicode=true&CharSet=utf8mb4&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&autoReconnectForPools=true&rewriteBatchedStatements=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
                username: XXXX
                password: XXXX
              initial-size: 2
              min-idle: 5
              max-active: 10
              max-wait: 5000
              validation-query: SELECT 1
              test-on-borrow: false
              test-while-idle: true
              time-between-eviction-runs-millis: 18800
              web-stat-filter:
                enabled: true
                exclusions: js,gif,jpg,png,css,ico,/druid/*
              stat-view-servlet:
                enabled: true
                login-username: root
                login-password: druid2019
          jpa:
            hibernate:
              ddlAuto: update
            databasePlatform: org.hibernate.dialect.MySQL5InnoDBDialect
            showSql: true
      • 注意
        • yml文件中之所以把driverClassName放到datasource下面,是因为这个datasource属性是两个数据源共有的信息,所以可以共享。完全可以把driverClassName单独配置到每个数据源当中,效果是一样的
    • 配置primary和secondary两个数据源
      • package ***************************;
        
        import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
        import org.slf4j.Logger;
        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;
        
        /**
         * @author *******
         * @Description: 多数据源配置
         * @date 2020/4/22
         */
        @Configuration
        public class DataSourceConfig {
        
            private static final Logger log = org.slf4j.LoggerFactory.getLogger(DataSourceConfig.class);
        
            @Primary
            @Bean(value = "primaryDataSource",initMethod = "init")
            @ConfigurationProperties("spring.datasource.druid.primary") //标红为yml文件中数据源路径:primary
            public DataSource dataSourceOne(){
                log.info("Init DataSourceOne");
                return DruidDataSourceBuilder.create().build();
            }
        
            @Bean(value = "secondDataSource",initMethod = "init")
            @ConfigurationProperties("spring.datasource.druid.secondary")//标红为yml文件中数据源路径:secondary
            public DataSource dataSourceTwo(){
                log.info("Init DataSourceTwo");
                return DruidDataSourceBuilder.create().build();
            }
        }
      • 注意
        • 多数据源配置时,一定要区分主数据源和其他数据源。所以在主数据源初始化时一定要加上注解@Peimary,其余数据源初始化不可以使用这个注解,否则报错。
    • 对应不同的数据源,需要匹配不同的JPA
      • 主数据源primary JPA配置如下
        • package ***************************;
          
          /**
           * @author ******
           * @Description: 主数据源 配置
           * @date 2020/4/22
           */
          
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
          import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
          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.xxxx.xxxxx.xxxxx.xxxx.repositories.mysql.record"}) //设置Repository所在位置
          public class PrimaryJpaConfig {
              @Autowired
          //    @Qualifier("primaryJpaProperties")
              private JpaProperties jpaProperties;
              @Autowired
              private HibernateProperties hibernateProperties;
          
              @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(jpaProperties.getProperties())// 设置jpa配置
                          .properties(getVendorProperties())// 设置hibernate配置
                          .packages("com.xxxxx.xxxxx.xxxx.xxxxx.entities.superviser") //设置实体类所在位置
                          .persistenceUnit("primaryPersistenceUnit")// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
                          .build();
              }
          
              private Map getVendorProperties() {
                  return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
          
          //        return jpaProperties.getHibernateProperties(new HibernateSettings());
              }
          
              @Primary
              @Bean(name = "transactionManagerPrimary")
              public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
                  return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
              }
          
          }
        • 注意
          • 主数据源JPA配置中,相对应的注入bean一定要加上注解@Primary,否则报错
      • 第二数据源JPA配置如下
        • package *********************;
          
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
          import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
          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;
          
          /**
           * @author ********
           * @Description: 第二数据源配置
           * @date 2020/4/22
           */
          @Configuration
          @EnableTransactionManagement
          @EnableJpaRepositories(
                  entityManagerFactoryRef = "entityManagerFactorySecond",
                  transactionManagerRef = "transactionManagerSecond",
                  basePackages = {"com.xxxxx.xxxxx.xxxx.xxxxx.repositories.mysql.integration"}) //设置Repository所在位置
          public class SecondJpaConfig {
              @Autowired
          //    @Qualifier("secondJpaProperties")
              private JpaProperties jpaProperties;
              @Autowired
              private HibernateProperties hibernateProperties;
          
              @Autowired
              @Qualifier("secondDataSource")
              private DataSource secondDataSource;
          
              @Bean(name = "secondEntityManager")
              public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
                  return entityManagerFactorySecond(builder).getObject().createEntityManager();
              }
          
              @Bean(name = "entityManagerFactorySecond")
              public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond(EntityManagerFactoryBuilder builder) {
                  return builder
                          .dataSource(secondDataSource)
                          .properties(jpaProperties.getProperties())// 设置jpa配置
                          .properties(getVendorProperties())
                          .packages("com.xxxxxx.xxxxxx.xxxxxx.xxxxx.entities.integration") //设置实体类所在位置
                          .persistenceUnit("secondPersistenceUnit")
                          .build();
              }
          
              private Map getVendorProperties() {
                  return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
          
          //        return jpaProperties.getHibernateProperties(new HibernateSettings());
              }
          
              @Bean(name = "transactionManagerSecond")
              public PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {
                  return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());
              }
          }
        • 注意
          • 除了主数据源,其他数据源JPA配置中,bean的注入方法都不能使用注解@Primary,否则报错
    • 成功启动

    注意点

    • @Primary注解的使用
    • 目录结构中,JPA目录和实体类目录建议根据多数据源的配置进行分层,因为在多数据源配置中存在相关配置
  • 相关阅读:
    Vue优化首页加载速度 CDN引入
    vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践
    node.js
    keep-alive前进没有刷新
    移动端ios和安卓input问题
    前端技术原理
    Vue给子组件传值为空
    使用vue开发输入型组件更好的一种解决方式(子组件向父组件传值,基于2.2.0)
    Vue路由参数设置可有可无
    Vue组件的三种调用方式
  • 原文地址:https://www.cnblogs.com/zuiyue_jing/p/12757307.html
Copyright © 2011-2022 走看看