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. SecondaryConfig

      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包结构


       

    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);
          }
      }
      

        

posted @ 2018-09-21 15:18  coderjinjian  阅读(2126)  评论(2编辑  收藏  举报