使用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.Driverjdbc-url: jdbc:mariadb://xxx/xxx?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghaiusername: 123password: 123#从数据库secondary: #名字可以自定driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriverjdbc-url: jdbc:sqlserver://www.xx.com:xx/xx?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghaiusername: 123password: 123jpa:hibernate:#方言primary-dialect: org.hibernate.dialect.MySQL5InnoDBDialectsecondary-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();}@Autowiredprivate JpaProperties jpaProperties;@Autowiredprivate 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();}@Autowiredprivate JpaProperties jpaProperties;@Autowiredprivate 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层接口 即可使用不同的数据库!