<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
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
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(); } }
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; } }
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; } }
POJO與Repository包結構
mysql
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); } }