springboot configure multiple data sources of actual cases

Abstract: The code address https://github.com/java-open/springboot-integration "Public number: Tianshan clouds' attention and welcome to reprint, cherish every encounter, thank you!

I. Introduction:

Work will encounter such business circumstances, we will put the data in different databases, a business need to connect to different data sources to manipulate data. This time springboot need to configure multiple data sources.

By the following example demonstrates how:
the User user table in the main library master, on the table from the library cluster address city. Here achieve access for user information based on the user name, the address information comprising the REST API library, you need, and business logic returns to the main assembly of the library from the library and obtain data from, respectively.

Second, prepare the database

1. Database prepare
a database to create a cluster springbootdb_cluster:.
The CREATE DATABASE springbootdb_custer;

. B create a table city:

DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '城市编号',
`province_id` int(10) unsigned NOT NULL COMMENT '省份编号',
`city_name` varchar(25) DEFAULT NULL COMMENT '城市名称',
`description` varchar(25) DEFAULT NULL COMMENT '描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Insert data c.
the INSERT City the VALUES (. 1,. 1 'Shanghai' 'is a magic magical and cold city.');

1.2 and then create a master database

. a Create a database springbootdb_master:
the CREATE DATABASE springbootdb_cluster;

. B create a table user:

DROP TABLE IF EXISTS `user`;
CREATE TABLE user
(
id INT(10) unsigned PRIMARY KEY NOT NULL COMMENT '用户编号' AUTO_INCREMENT,
user_name VARCHAR(25) COMMENT '用户名称',
description VARCHAR(25) COMMENT '描述'
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

. c insert data
( '! person under a' 1, 'Zhang Tian',) INSERT user VALUES;

1.3. Change the project configuration database
open application.properties file, modify the main configuration from a data source, such as a data source address, account number, password and so on. (If not using MySQL, add their own drive connection pom, and then modify the drive name of the configuration.)

Three, springboot-mybatis-mutil-datasource Projects

First, the code works is structured as follows:

resources / mapper following two modules, namely, the directory mapper xml Mybatis different data sources to be scanned

  1. Dependent the pom.xml
    Mybatis by Spring Boot Mybatis Starter dependent
    Druid dependent database connection pool
<?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>springboot</groupId>
    <artifactId>springboot-mybatis-mutil-datasource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-mybatis-mutil-datasource :: Spring Boot 实现 Mybatis 多数据源配置</name>

    <!-- Spring Boot 启动父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

    <properties>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>5.1.39</mysql-connector>
        <druid>1.0.18</druid>
    </properties>

    <dependencies>

        <!-- Spring Boot Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Test 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Spring Boot Mybatis 依赖 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>

        <!-- MySQL 连接驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector}</version>
        </dependency>

        <!-- Druid 数据连接池依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid}</version>
        </dependency>

        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>
  1. application.properties arranged two data sources configured
    data source configuration data source is the data source is configured as follows
## master 数据源配置
master.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8
master.datasource.username=root
master.datasource.password=123456
master.datasource.driverClassName=com.mysql.jdbc.Driver

## cluster 数据源配置
cluster.datasource.url=jdbc:mysql://localhost:3306/springbootdb_cluster?useUnicode=true&characterEncoding=utf8
cluster.datasource.username=root
cluster.datasource.password=123456
cluster.datasource.driverClassName=com.mysql.jdbc.Driver
  1. Data source configuration
    plurality of configuration data when the source is noted that there must be a master data source, i.e. MasterDataSourceConfig configuration:

If this flag @Primary Bean Bean when more of the same candidate, the Bean be given precedence. "Multi data source configuration when the attention, there must be a master data source, with @Primary sign the Bean"
@MapperScan scanning Mapper interfaces and container management, including precise path to the master, and cluster data source for the following to be precise distinction
@ Value obtain the global configuration file application.properties kv configuration, and automatic assembly
sqlSessionFactoryRef represented defined key, it represents a unique example SqlSessionFactory

@Configuration
// 扫描 Mapper 接口并容器管理
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {

    // 精确到 master 目录,以便跟其他数据源隔离
    static final String PACKAGE = "com.spring.springboot.dao.master";
    static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";

    @Value("${master.datasource.url}")
    private String url;

    @Value("${master.datasource.username}")
    private String user;

    @Value("${master.datasource.password}")
    private String password;

    @Value("${master.datasource.driverClassName}")
    private String driverClass;

    @Bean(name = "masterDataSource")
    @Primary
    public DataSource masterDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager() {
        return new DataSourceTransactionManager(masterDataSource());
    }

    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(masterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
        return sessionFactory.getObject();
    }
}

Similarly available, from a data source ClusterDataSourceConfig configured as follows:

@Configuration
// 扫描 Mapper 接口并容器管理
@MapperScan(basePackages = ClusterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory")
public class ClusterDataSourceConfig {

    // 精确到 cluster 目录,以便跟其他数据源隔离
    static final String PACKAGE = "com.spring.springboot.dao.cluster";
    static final String MAPPER_LOCATION = "classpath:mapper/cluster/*.xml";

    @Value("${cluster.datasource.url}")
    private String url;

    @Value("${cluster.datasource.username}")
    private String user;

    @Value("${cluster.datasource.password}")
    private String password;

    @Value("${cluster.datasource.driverClassName}")
    private String driverClass;

    @Bean(name = "clusterDataSource")
    public DataSource clusterDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean(name = "clusterTransactionManager")
    public DataSourceTransactionManager clusterTransactionManager() {
        return new DataSourceTransactionManager(clusterDataSource());
    }

    @Bean(name = "clusterSqlSessionFactory")
    public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource clusterDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(clusterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(ClusterDataSourceConfig.MAPPER_LOCATION));
        return sessionFactory.getObject();
    }
}

上面数据配置分别扫描 Mapper 接口,分别对应 包中的 UserDAO 和 CityDAO 。
都有 @Mapper 标志为 Mybatis 的并通过容器管理的 Bean。Mybatis 内部会使用反射机制运行去解析相应 SQL。

4.根据表生成实体类,dao,mapper等

5.业务层代码:
编写controller层代码,根据传入的name值,然后查询主从两个数据内容
UserController层

/**
 *控制层
 */
@RestController
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 通过用户名获取用户信息,以及从库的地址信息
     */
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public User findUserByName(@RequestParam(value = "name",required = true) String name){
        return  userService.findByName(name);

    }
}

Service层
照常注入主从两个Dao层

@Service
public class UserService {


    @Autowired
    private UserDao userDao; // 主数据源

    @Autowired
    private CityDao cityDao; // 从数据源


    public User findByName(String userName) {
        User user = userDao.findByName(userName);
        City city = cityDao.findByName("上海市");
        System.out.println(city);
        user.setDescription("从数据库->"+city.getDescription());
        user.setCity(city);
        return user;
    }
}

6.访问接口路径,测试结果包含两个数据库内容

右键运行Application 启动类,然后再浏览器输入接口路径测试结果

四、总结
多数据源适合的场景很多。不同的 DataSource ,不同的 SqlSessionFactory 和 不同的 DAO 层,在业务逻辑层做 整合。
需要参考完整代码的请参考:
github地址:https://github.com/java-open/springboot-integration

参考链接:
https://mp.weixin.qq.com/s/sxvWSfBbWbiI91B6rQb66A
https://www.bysocket.com/technique/1712.html

Guess you like

Origin www.cnblogs.com/tsyh/p/11946529.html