Spring多数据源配置实战指南

多数据源配置实现

application.yml配置
spring:
  application:
    name: multi-datasource-demo

master:
  datasource:
    username: root
    password: root123
    url: jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    initial-size: 5
    min-idle: 5
    max-active: 20
    max-wait: 60000
    time-between-eviction-runs-millis: 60000
    min-evictable-idle-time-millis: 300000
    validation-query: SELECT 1
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false

second:
  datasource:
    username: root
    password: root456
    url: jdbc:mysql://1.117.14.204:3306/library?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    initial-size: 5
    min-idle: 5
    max-active: 20
    max-wait: 60000
    time-between-eviction-runs-millis: 60000
    min-evictable-idle-time-millis: 300000
    validation-query: SELECT 1
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false

mybatis:
  configuration:
    map-underscore-to-camel-case: true
    default-fetch-size: 100
    default-statement-timeout: 30

主数据源配置类
package com.example.multidatasource.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(
    basePackages = MasterDataSourceConfig.PACKAGE,
    sqlSessionFactoryRef = "masterSqlSessionFactory"
)
public class MasterDataSourceConfig {

    static final String PACKAGE = "com.example.multidatasource.dao.master";
    static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";

    @Primary
    @Bean(name = "masterDataSource")
    @ConfigurationProperties("master.datasource")
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

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

    @Primary
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(
            @Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }
}

第二数据源配置类
package com.example.multidatasource.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(
    basePackages = SecondDataSourceConfig.PACKAGE,
    sqlSessionFactoryRef = "secondSqlSessionFactory"
)
public class SecondDataSourceConfig {

    static final String PACKAGE = "com.example.multidatasource.dao.second";
    static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";

    @Bean(name = "secondDataSource")
    @ConfigurationProperties("second.datasource")
    public DataSource secondDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "secondTransactionManager")
    public DataSourceTransactionManager secondTransactionManager(
            @Qualifier("secondDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory secondSqlSessionFactory(
            @Qualifier("secondDataSource") DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(SecondDataSourceConfig.MAPPER_LOCATION));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }
}

实体类与Mapper接口

主数据源实体类定义学生信息,包含id、name、age和email字段:

@Data
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

主数据源Mapper接口通过注解实现查询:

@Mapper
public interface StudentMapper {
    @Select("SELECT * FROM student WHERE id = #{id}")
    Student selectById(Long id);
}

第二数据源实体类定义书籍信息,包含id、title、author和isbn字段:

@Data
public class Book {
    private Long id;
    private String title;
    private String author;
    private String isbn;
}

第二数据源Mapper接口通过注解实现查询:

@Mapper
public interface BookMapper {
    @Select("SELECT * FROM book WHERE id = #{id}")
    Book selectById(Long id);
}

XML映射文件配置

主数据源Mapper XML文件配置结果映射和查询语句:

<resultMap id="BaseResultMap" type="com.example.multidatasource.model.master.Student">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="age" property="age"/>
    <result column="email" property="email"/>
</resultMap>
<select id="selectById" resultMap="BaseResultMap">
    SELECT * FROM student WHERE id = #{id}
</select>

第二数据源Mapper XML文件配置结果映射和查询语句:

<resultMap id="BaseResultMap" type="com.example.multidatasource.model.second.Book">
    <id column="id" property="id"/>
    <result column="title" property="title"/>
    <result column="author" property="author"/>
    <result column="isbn" property="isbn"/>
</resultMap>
<select id="selectById" resultMap="BaseResultMap">
    SELECT * FROM book WHERE id = #{id}
</select>

控制器实现

测试控制器包含两个数据源的查询方法:

@RestController
@RequestMapping("/api")
public class DataSourceTestController {
    private final StudentMapper studentMapper;
    private final BookMapper bookMapper;

    @Autowired
    public DataSourceTestController(StudentMapper studentMapper, BookMapper bookMapper) {
        this.studentMapper = studentMapper;
        this.bookMapper = bookMapper;
    }

    @GetMapping("/student/{id}")
    public Student getStudent(@PathVariable Long id) {
        return studentMapper.selectById(id);
    }

    @GetMapping("/book/{id}")
    public Book getBook(@PathVariable Long id) {
        return bookMapper.selectById(id);
    }
}

应用启动配置

主类需排除自动数据源配置:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MultiDataSourceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MultiDataSourceApplication.class, args);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值