SSH專案整合多資料來源
阿新 • • 發佈:2020-12-19
技術標籤:專案常見問題spring boot專案架構hibernate
這裡以雙資料來源為例
前言
現在有的專案需要取不同資料庫的資料,這時就需要多個數據源。spring框架已經很完善了,不需要我們再去配置繁瑣的xml,我們只需要在配置檔案中配置多個數據源,然後在不同的場景讀取不同的資料資訊就可以搞定。本篇文章將以分包的方式配置雙資料來源
正文
首先我們需要配置兩個資料來源,下面是以Mysql和PostGresql兩個不同的資料庫為例,配置資訊的字首需要不一致,以區分不同的資料來源。
#主
spring.datasource.jdbc-url=jdbc:mysql://${DATA_BASE_IP_NAME:} ?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=${DATA_BASE_USERNAME:}
spring.datasource.password=${DATA_BASE_PASSWORD:}
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.validation-timeout=3000
#從
spring.slave.datasource.jdbc-url=jdbc:postgresql://${DATA_BASE_IP_NAME_POSTGRE:}?searchpath=hrmw¤tSchema=hrmw&useUnicode=true&characterEncoding= utf8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.slave.datasource.driver-class-name=org.postgresql.Driver
spring.slave.datasource.username=${DATA_BASE_USERNAME_POSTGRE:}
spring.slave.datasource.password=${DATA_BASE_PASSWORD_POSTGRE:
spring.slave.datasource.hikari.maximum-opol-size=10
spring.slave.datasource.hikari.connection-timeout=60000
spring.slave.datasource.hikari.validation-timeout=3000
然後就是需要配置檔案來讀取指定的資料來源,DataSourceConfig 注入兩個Bean的資料來源,分別是master和slave,通過配置檔案的字首來讀取。
@Configuration
public class DataSourceConfig {
@Bean("master")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
@Bean("slave")
@ConfigurationProperties(prefix = "spring.slave.datasource")
public DataSource dataSourceSlave(){
return DataSourceBuilder.create().build();
}
}
Spring除了資料來源還需要事務管理器,所以我們需要給兩個資料來源分別配置兩個資料管理器。MasterDataSourceConfig 主事務管理器對應master資料來源,
SlaveDataSourceConfig 從事務管理器對應slave資料來源
對於文中的兩個basePackages 需要根據自己專案的分包情況修改。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryMaster1",//配置連線工廠 entityManagerFactory
transactionManagerRef = "transactionManagerMaster1", //配置 事物管理器 transactionManager
basePackages = {"com.test.test.repository1"} //這個地方根據自己的模組修改
)
public class MasterDataSourceConfig {
@Autowired
@Qualifier("master")
private DataSource dataSourceMaster;
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerMaster1")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean("entityManagerFactoryMaster1")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceMaster)
.properties(jpaProperties.getProperties())
.packages("com.test.test.pojo1") // 這個地方根據自己的模組修改
//持久化單元名稱,當存在多個EntityManagerFactory時,需要制定此名稱
.persistenceUnit("masterPersistenceUnit")
.build();
}
@Bean("transactionManagerMaster1")
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryMaster2",//配置連線工廠 entityManagerFactory
transactionManagerRef = "transactionManagerMaster2", //配置 事物管理器 transactionManager
basePackages = {"com.test.test.repository2"} //這個地方根據自己的模組修改
)
public class SlaveDataSourceConfig {
@Autowired
@Qualifier("slave")
private DataSource dataSourceSlave;
@Autowired
private JpaProperties jpaProperties;
@Bean("entityManagerMaster2")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryBean(builder).getObject().createEntityManager();
}
@Bean("entityManagerFactoryMaster2")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceSlave)
.properties(jpaProperties.getProperties())
.packages("com.test.test.pojo2") //這個地方根據自己的模組修改
//持久化單元名稱,當存在多個EntityManagerFactory時,需要制定此名稱
.persistenceUnit("slavePersistenceUnit")
.build();
}
@Bean("transactionManagerMaster2")
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
}
}
專案分包情況:
在pojo1和repository1中存放的是mysql庫的專案的相關資訊。
在pojo2和repository2中存放的是pg庫的專案的相關資訊。
根據包的全命名修改上面配置類的名稱。
這樣雙資料來源就配置完成了,mysql相關的sql寫在pojo1和repository1中,pg相關的程式碼寫在pojo2和repository2中,service層可以公用一個。這樣就可以通過分包的方法配置雙資料來源。
結束
青春是有限的,智慧是無窮的,趁短的青春,去學習無窮的智慧,加油各位程式猿。