使用spring boot jpa 配置多数据源
由于项目整合 以前的功能 但是以前功能存储的数据库是另一个数据库
这两天搜索了一下 遇见了许多坑 在这里记录一下
首先附上我的项目结构
可能有些乱 忘见谅。
pom.xml(把数据库的依赖引入)
<!-- mariadb -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
<!--sql server数据库-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
修改yml配置文件
spring:
datasource:
#主数据库
primary: #名字可以自定
driver-class-name: org.mariadb.jdbc.Driver
jdbc-url: jdbc:mariadb://xxx/xxx?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
username: 123
password: 123
#从数据库
secondary: #名字可以自定
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url: jdbc:sqlserver://www.xx.com:xx/xx?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
username: 123
password: 123
jpa:
hibernate:
#方言
primary-dialect: org.hibernate.dialect.MySQL5InnoDBDialect
secondary-dialect: org.hibernate.dialect.SQLServerDialect
#ddl-auto: validate
# create 启动时删数据库中的表,然后创建,退出时不删除数据表
# create-drop 启动时删数据库中的表,然后创建,退出时删除数据表 如果表不存在报错
# update 如果启动时表格式不一致则更新表,原有数据保留
# validate 项目启动表结构进行校验 如果不一致则报错
show-sql: true
然后需要配置类
DataSourceConfig–配置数据源
import org.springframework.beans.factory.annotation.Qualifier;
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;
/**
* 读取application.yml配置的两个数据源,并将其注入到Spring的IOC容器中
*/
@Configuration //SpringBoot启动将该类作为配置类,同配置文件一起加载
public class DataSourceConfig {
//将该实体注入到IOC容器中
@Bean(name = "primaryDataSource")
//指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功
@Qualifier("primaryDataSource")
//指定主数据源
@Primary
//将配置文件中的数据源读取进到方法中,进行build
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
//将该实体注入到IOC容器中
@Bean(name = "secondaryDataSource")
//指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功
@Qualifier("secondaryDataSource")
//将配置文件中的数据源读取进到方法中,进行build
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
然后是配置主数据库
PrimaryConfig
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.core.env.Environment;
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.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 主数据源
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"com.xx.mysql.dao"}) // 指定该数据源操作的DAO接口包
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Value("${spring.jpa.hibernate.primary-dialect}")
private String primaryDialect;//获取方言
@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(getVendorProperties())
.packages("com.xx.mysql.pojo") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
Map<String,String> map = new HashMap<>();
map.put("hibernate.dialect",primaryDialect);// 设置对应的数据库方言
map.put("hibernate.ddl-auto","validate");//项目启动表结构进行校验 如果不一致则报错
jpaProperties.setProperties(map);
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());
}
}
由于我使用的版本是springboot 2.1 在这里jpaProperties 没有了getHibernateProperties方法!!!
然后是从数据库
SecondaryConfig
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.core.env.Environment;
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.HashMap;
import java.util.Map;
/**
* 从数据源
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {"com.xx.sqlServer.dao"}) //设置DAO接口层所在包位置
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Value("${spring.jpa.hibernate.secondary-dialect}")
private String secondaryDialect;//获取方言
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource)
.properties(getVendorProperties())
.packages("com.xx.sqlServer.pojo") //设置实体类所在包的位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
Map<String,String> map = new HashMap<>();
map.put("hibernate.dialect",secondaryDialect);
map.put("hibernate.ddl-auto","validate");
jpaProperties.setProperties(map);
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
这样就配置好了 !!!
引用的时候只需要引入对应的dao层接口 即可使用不同的数据库!