springboot-jpa多數據源

  1. Maven依賴
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
  2. application.yml
    spring:
      datasource: #默認type:HikariDataSource 號稱java最快的鏈接池
        primary:
          jdbcUrl: jdbc:mysql://127.0.0.1:3306/heyday?useUnicode=true&characterEncoding=utf8
          username: root
          password: root
          maximum-pool-size: 30
          minimum-idle: 5
        secondary:
          jdbcUrl: jdbc:mysql://127.0.0.1:3306/heyday2?useUnicode=true&characterEncoding=utf8
          username: root
          password: root
          maximum-pool-size: 30
          minimum-idle: 5
    
      jpa:
        hibernate:
          naming:
            physical-strategy:    org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
            implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
  3. Java配置類

    1. DataSourceConfig
      package com.jinjian.demo.config;
      
      import com.zaxxer.hikari.HikariDataSource;
      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("primaryDataSource")
          @Primary
          @ConfigurationProperties("spring.datasource.primary")
          public DataSource primaryDataSource() {
              return DataSourceBuilder.create().type(HikariDataSource.class).build();  //返回的DataSource對象會被@ConfigurationProperties進行屬性注入
          }
      
          @Bean("secondaryDataSource")
          @ConfigurationProperties("spring.datasource.secondary")
          public DataSource secondaryDataSource() {
              return DataSourceBuilder.create().type(HikariDataSource.class).build();
          }
      
      }
      

       

    2. PrimaryConfig
      package com.jinjian.demo.config;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
      import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
      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.orm.jpa.vendor.Database;
      import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
      import org.springframework.transaction.PlatformTransactionManager;
      import org.springframework.transaction.annotation.EnableTransactionManagement;
      
      import javax.sql.DataSource;
      import java.util.Map;
      
      
      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
              entityManagerFactoryRef="entityManagerFactoryPrimary",
              transactionManagerRef="transactionManagerPrimary",
              basePackages= { "com.jinjian.demo.repository.primary" })
      public class PrimaryConfig {
      
          @Autowired
          @Qualifier("primaryDataSource")
          private DataSource primaryDataSource;
      
          @Autowired private JpaProperties jpaProperties; //Jpa自帶的一個讀取jpa屬性的類
      
          @Bean("entityManagerFactoryPrimary")
          @Primary
          public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary() {
      
              HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
              vendorAdapter.setGenerateDdl(true); //hibernate基本配置
              vendorAdapter.setDatabase(Database.MYSQL);
              vendorAdapter.setShowSql(true);
      
              LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
              factory.setJpaVendorAdapter(vendorAdapter);
              factory.setPackagesToScan("com.jinjian.demo.pojo.primary"); //實體掃描
              factory.setDataSource(primaryDataSource); 
      
              Map<String, Object> hibernateProperties = jpaProperties.getHibernateProperties(new HibernateSettings());
              factory.setJpaPropertyMap(hibernateProperties);  //主要目的:讀取application.yml的naming-strategy,並設置進去,否則實體屬性與表字段之間沒法進行駝峯->下劃線的自動轉換,原本默認就是自動轉換的。可是你是配的多個自定義數據源,spring特性之一,一旦自定義,默認不生效,瞭解一下...
         return factory; } @Bean("transactionManagerPrimary") @Primary public PlatformTransactionManager transactionManagerPrimary() { //事務管理器:事務不能跨數據源,跨數據源,事務是不生效的。使用事務時,最好要指明使用哪一個事務管理器,否則就會默認使用primary修飾的事務管理器 JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactoryPrimary().getObject()); return txManager; } }

       

    3. SecondaryConfigjava

      package com.jinjian.demo.config;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
      import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
      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.orm.jpa.vendor.Database;
      import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
      import org.springframework.transaction.annotation.EnableTransactionManagement;
      
      import javax.sql.DataSource;
      import java.util.Map;
      
      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
              entityManagerFactoryRef="entityManagerFactorySecondary",
              transactionManagerRef="transactionManagerSecondary",
              basePackages= { "com.jinjian.demo.repository.secondary" })
      public class SecondaryConfig {
      
          @Autowired
          @Qualifier("secondaryDataSource")
          private DataSource secondaryDataSource;
      
          @Autowired
          private JpaProperties jpaProperties;
      
          @Bean("entityManagerFactorySecondary")
          public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary() {
              HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
              vendorAdapter.setGenerateDdl(true);
              vendorAdapter.setDatabase(Database.MYSQL);
              vendorAdapter.setShowSql(true);
      
              LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
              factory.setJpaVendorAdapter(vendorAdapter);
              factory.setPackagesToScan("com.jinjian.demo.pojo.secondary");
              factory.setDataSource(secondaryDataSource);
      
              Map<String, Object> hibernateProperties = jpaProperties.getHibernateProperties(new HibernateSettings());
              factory.setJpaPropertyMap(hibernateProperties);
              return factory;
          }
      
      
          @Bean("transactionManagerSecondary")
          public JpaTransactionManager transactionManagerSecondary() {
              JpaTransactionManager transactionManager = new JpaTransactionManager();
              transactionManager.setEntityManagerFactory(entityManagerFactorySecondary().getObject());
              return transactionManager;
          }
      }
      

        

    4.  

      POJO與Repository包結構


       mysql

    5. 如何在service中使用
      package com.jinjian.demo.service;
      
      import com.jinjian.demo.pojo.secondary.Tclient;
      import com.jinjian.demo.repository.secondary.TclientRepository;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      import org.springframework.transaction.annotation.Transactional;
      
      @Service
      public class TclientService {
      
          @Autowired
          private TclientRepository tclientRepository;
      
          @Transactional("transactionManagerSecondary") //非主事務管理器,必須寫明用的是哪一個,否則用的別就是默認數據源的事務管理器,就無效。
          public void addTclient(Tclient tclient){
              tclientRepository.delete(tclient);
              if (1 == 1){
                  throw new RuntimeException("測試");
              }
              tclientRepository.save(tclient);
          }
      }
      
相關文章
相關標籤/搜索