很多业务场景都需要使用到多数据库,本文介绍springboot对多数据源的使用。
这次先说一下application.properties文件,分别连接了2个数据库test和test1。完整代码如下:
##端口号 server.port=8888 ##数据库url spring.datasource.test.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false ##数据库用户名 spring.datasource.test.username=root ##数据库密码 spring.datasource.test.password=root ##数据库驱动 spring.datasource.test.driver-class-name=com.mysql.jdbc.Driver ##数据库url spring.datasource.test2.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8&useSSL=false ##数据库用户名 spring.datasource.test2.username=root ##数据库密码 spring.datasource.test2.password=root ##数据库驱动 spring.datasource.test2.driver-class-name=com.mysql.jdbc.Driver spring.jpa.hibernate.ddl-auto=create ##控制台打印sql spring.jpa.show-sql=true
然后说一下处理多数据源的DataSourceConfig,其中@ConfigurationProperties注解对应刚才的数据库,而且这个重点是一定要有一个主数据源,并且在上面加上@Primary,代码如下:
package com.dalaoyang.config; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.config * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ @Configuration public class DataSourceConfig { @Bean(name = "testDataSource") @Qualifier("testDataSource") @ConfigurationProperties(prefix="spring.datasource.test") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "test2DataSource") @Qualifier("test2DataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.test2") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } }
接下来是对应test数据库的配置,其中需要说一下的是@EnableJpaRepositories注解里面的basePackages属性对应的是这个数据源对应的repository(因为本文使用的是jpa), @Qualifier注解内的value要和DataSourceConfig的值一致即可。
代码如下:
package com.dalaoyang.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; 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.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.Map; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.config * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "com.dalaoyang.repository.datasource" }) public class TestDataSourceConfig { @Autowired @Qualifier("testDataSource") private DataSource dataSource; @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(dataSource) .properties(getVendorProperties(dataSource)) .packages("com.dalaoyang.entity.datasource") //设置实体类所在位置 .persistenceUnit("primaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map<String, String> getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
Test2DataSourceConfig就不多说了,和TestDataSourceConfig原理一致,代码如下:
package com.dalaoyang.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; 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.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.Map; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.config * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "com.dalaoyang.repository.datasource2" }) //设置Repository所在位置 public class Test2DataSourceConfig { @Autowired @Qualifier("test2DataSource") private DataSource dataSource; @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) { return builder .dataSource(dataSource) .properties(getVendorProperties(dataSource)) .packages("com.dalaoyang.entity.datasource2") //设置实体类所在位置 .persistenceUnit("secondaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map<String, String> getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
下面是对应的model和repository
City类
package com.dalaoyang.entity.datasource; import javax.persistence.*; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.Entity * @email 397600342@qq.com * @date 2018/4/7 */ @Entity @Table(name="city") public class City { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int cityId; private String cityName; private String cityIntroduce; public City(int cityId, String cityName, String cityIntroduce) { this.cityId = cityId; this.cityName = cityName; this.cityIntroduce = cityIntroduce; } public City(String cityName, String cityIntroduce) { this.cityName = cityName; this.cityIntroduce = cityIntroduce; } public City() { } public int getCityId() { return cityId; } public void setCityId(int cityId) { this.cityId = cityId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getCityIntroduce() { return cityIntroduce; } public void setCityIntroduce(String cityIntroduce) { this.cityIntroduce = cityIntroduce; } }
House类
package com.dalaoyang.entity.datasource2; import javax.persistence.*; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.entity * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ @Entity @Table(name="house") public class House { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int houseId; private String houseName; private String houseIntroduce; public int getHouseId() { return houseId; } public void setHouseId(int houseId) { this.houseId = houseId; } public String getHouseName() { return houseName; } public void setHouseName(String houseName) { this.houseName = houseName; } public String getHouseIntroduce() { return houseIntroduce; } public void setHouseIntroduce(String houseIntroduce) { this.houseIntroduce = houseIntroduce; } public House(String houseName, String houseIntroduce) { this.houseName = houseName; this.houseIntroduce = houseIntroduce; } }
CityRepository
package com.dalaoyang.repository.datasource; import com.dalaoyang.entity.datasource.City; import org.springframework.data.jpa.repository.JpaRepository; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.Repository * @email 397600342@qq.com * @date 2018/4/7 */ public interface CityRepository extends JpaRepository<City,Integer> { }
HouseRepository
package com.dalaoyang.repository.datasource2; import com.dalaoyang.entity.datasource2.House; import org.springframework.data.jpa.repository.JpaRepository; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.repository.datasource2 * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ public interface HouseRepository extends JpaRepository<House,Integer> { }
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dalaoyang</groupId> <artifactId>springboot_datasources</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot_datasources</name> <description>springboot_datasources</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
因为上面这些都没什么可说的,都是和正常的写法没什么区别,最后是TestController测试类
package com.dalaoyang.controller; import com.dalaoyang.entity.datasource.City; import com.dalaoyang.entity.datasource2.House; import com.dalaoyang.repository.datasource.CityRepository; import com.dalaoyang.repository.datasource2.HouseRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author dalaoyang * @Description * @project springboot_learn * @package com.dalaoyang.controller * @email yangyang@dalaoyang.cn * @date 2018/4/10 */ @RestController public class TestController { @Autowired CityRepository cityRepository; @Autowired HouseRepository houseRepository; @GetMapping("/testDataSource") public String testDataSource(){ City city = new City("北京","中国首都"); cityRepository.save(city); return "success"; } @GetMapping("/testDataSource2") public String testDataSource2(){ House house = new House("豪宅","特别大的豪宅"); houseRepository.save(house); return "success"; } }
启动项目可以看到test数据库中新建了city表,test2数据库中新建了house表。