SpringBoot多資料來源

flynike發表於2021-09-09

很多業務場景都需要使用到多資料庫,本文介紹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 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 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 {
}

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 {
}

pom檔案

4.0.0com.dalaoyangspringboot_datasources0.0.1-SNAPSHOTjarspringboot_datasourcesspringboot_datasourcesorg.springframework.bootspring-boot-starter-parent1.5.9.RELEASE <!-- lookup parent from repository --&gt
	UTF-8UTF-81.8org.springframework.bootspring-boot-starter-data-jpaorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-devtoolsruntimemysqlmysql-connector-javaruntimeorg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-maven-plugin

因為上面這些都沒什麼可說的,都是和正常的寫法沒什麼區別,最後是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表。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2618/viewspace-2810753/,如需轉載,請註明出處,否則將追究法律責任。

相關文章