Spring Boot 整合多数据源

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cckevincyh/article/details/79187959

Spring Boot 整合多数据源

我们先创建一个maven项目:
这里写图片描述

创建两个数据库test01和test02,并且都创建一个user表
这里写图片描述

配置pom.xml

<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.cc.springboot</groupId>
  <artifactId>springboot-many-mybatis</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

配置文件中新增两个数据源

application.properties

spring.datasource.test1.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test1.url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = root

spring.datasource.test2.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test2.url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = root

创建分包Mapper

分包创建User1Mapper和User2Mapper
这里写图片描述

package com.cc.springboot.test01;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;

public interface User1Mapper {

    @Insert("insert into users values(#{id},#{username});")
    public int addUser(@Param("id") Integer id, @Param("username") String username);

}
package com.cc.springboot.test02;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;

public interface User2Mapper {

    @Insert("insert into users values(#{id},#{username});")
    public int addUser(@Param("id") Integer id, @Param("username") String username);
}

配置文件中新增两个数据源

这里写图片描述

package com.cc.springboot.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;



@Configuration // 注册到springboot容器中
@MapperScan(basePackages = "com.cc.springboot.test01", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {

    /** 
     *配置test1数据库
     */
    @Bean(name = "test1DataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.test1")
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }

    /* 
     * test1 sql会话工厂
     */
    @Bean(name = "test1SqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
//      bean.setMapperLocations(
//              new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
        return bean.getObject();
    }

    /**
     *test1 事物管理
     */
    @Bean(name = "test1TransactionManager")
    @Primary
    public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test1SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}
package com.cc.springboot.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;



@Configuration // 注册到springboot容器中
@MapperScan(basePackages = "com.cc.springboot.test02", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {

    /** 
     *配置test2数据库
     */
    @Bean(name = "test2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.test2")
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }

    /* 
     * test2 sql会话工厂
     */
    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
//      bean.setMapperLocations(
//              new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
        return bean.getObject();
    }

    /**
     *test2 事物管理
     */
    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test2SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

这里写图片描述

分包创建service

这里写图片描述

package com.cc.springboot.service.test01;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cc.springboot.test01.User1Mapper;


@Service
public class User1Service {
    @Autowired
    private User1Mapper user1Mapper;


    public int addUser(Integer id, String name) {
        return user1Mapper.addUser(id, name);
    }

}
package com.cc.springboot.service.test02;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cc.springboot.test02.User2Mapper;


@Service
public class User2Service {
    @Autowired
    private User2Mapper user2Mapper;


    public int addUser(Integer id, String name) {
        return user2Mapper.addUser(id, name);
    }

}

创建Controller

package com.cc.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cc.springboot.service.test01.User1Service;
import com.cc.springboot.service.test02.User2Service;


@RestController
public class IndexController {
    @Autowired
    private User1Service user1Service;
    @Autowired
    private User2Service user2Service;

    @RequestMapping("/add")
    public String index() {
        user1Service.addUser(1,"db user001");
        user2Service.addUser(2,"db user002");
        return "success";
    }

}

创建启动类

package com.cc.springboot.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = {"com.cc.springboot.controller","com.cc.springboot.test01","com.cc.springboot.test02","com.cc.springboot.service","com.cc.springboot.datasource"})
@EnableAutoConfiguration
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

测试

启动:
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

注意事项

如果去掉DataSource1Config配置中的@Primary会发生什么??
这里写图片描述

发现报错了:
这里写图片描述

错误原因:No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: test1DataSource,test2DataSource
给其中一个数据源加上@Primary。因为在Spring Boot Jdbc的自动配置过程中,会对于开发者透明地使用dataSource进行一些相关配置,所以当有两个Datasource实现类时,Spring Boot将无法确定使用哪一个。

DataSource1Config配置中的注解的具体解释:

  • @Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
  • @Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
  • @Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)

猜你喜欢

转载自blog.csdn.net/cckevincyh/article/details/79187959