上篇写过mybatis使用注解实现动态切换数据源,但是注解无法保证事务的原子性。而@DS可以实现事务的原子性,所以此篇使用@DS注解实现多数据源动态切换。

Maven jar包

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.2.1</version>
</dependency>

配置文件配置

数据源配置

spring.datasource.dynamic.primary=smdm
spring.datasource.dynamic.datasource.smdm.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.smdm.url=jdbc:mysql://10.130.16.185:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.dynamic.datasource.smdm.username=test
spring.datasource.dynamic.datasource.smdm.password=123456
spring.datasource.dynamic.datasource.smdm.druid.initial-size=5
spring.datasource.dynamic.datasource.smdm.druid.max-active=30
spring.datasource.dynamic.datasource.smdm.druid.min-idle=1
spring.datasource.dynamic.datasource.smdm.druid.max-wait=6000
spring.datasource.dynamic.datasource.smdm.druid.validation-query=SELECT 1
spring.datasource.dynamic.datasource.smdm.druid.test-on-borrow=true
spring.datasource.dynamic.datasource.smdm.druid.test-on-return=false
spring.datasource.dynamic.datasource.smdm.druid.test-while-idle=true

# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.dynamic.datasource.smdm.druid.min-evictable-idle-time-millis=300000
spring.datasource.dynamic.datasource.smdm.druid.max-evictable-idle-time-millis=300000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.dynamic.datasource.smdm.druid.time-between-eviction-runs-millis=600000
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.dynamic.datasource.smdm.druid.pool-prepared-statements=false
# 监控页面的登录账户、密码
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=~!@#$%`12345
# 开启驼峰功能
mybatis.configuration.map-underscore-to-camel-case=true
# 定义mapper接口位置的属性,在xxx.yml或xxx.properties下配置,作用是实现mapper接口配置
mybatis.mapper-locations=classpath*:mapper/*.xml

使用@DS注解代码

使用@DS说明

@DS(“dsName”) dsName 可以为组名也可以为具体某个库的名称。
@DS 可以注解在方法上和类上,同时存在方法注解优先于类注解,可以在server实现或mapper接口方法上,但强烈不建议同时在server和mapper注解上。
需要注意的是 如果使用PageHelper分页插件会有不切换数据源的情况发生,此时需加配置

#默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页
pagehelper.autoRuntimeDialect=true
# 会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,
# 设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定
pagehelper.closeConn=true
#分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询
pagehelper.reasonable=true
# druid数据源默认开启了自带的管理界面,如不需要则直接配置关闭即可
spring.datasource.druid.stat-view-servlet.enabled=false

代码实现

@RestController
@Slf4j
public class TestController {
    @Resource
    private IMdmScsCustomerManager mdmScsCustomerManager;

    @Resource
    private IMdmScsInfoManager mdmScsInfoManager;

    @GetMapping("/test/getMdmScsInfoManager")
    public void getMdmScsInfoManager() {
        String stationName = mdmScsInfoManager.getStationNameByCustomerCodeAndCabinetCode("CAINIAO", "21344");
        log.info("getMdmScsInfoManager:{}", JSON.toJSONString(stationName));
    }
}

如果有Service层时,在service与dao层之间加上manager作为与数据层处理。

public interface IMdmScsInfoManager {
    String getStationNameByCabinetCode(String cabinetCode);
    String getStationNameByCustomerCodeAndCabinetCode(String customerCode, String cabinetCode);
}

@DS("smdm")
@Service
public class MdmScsInfoManagerImpl implements IMdmScsInfoManager {
    @Resource
    private MdmScsInfoDao mdmScsInfoDao;

    @Override
    public String getStationNameByCabinetCode(String cabinetCode) {
        return mdmScsInfoDao.getStationNameByCabinetCode(cabinetCode);
    }

    @Override
    public String getStationNameByCustomerCodeAndCabinetCode(String customerCode, String cabinetCode) {
        return mdmScsInfoDao.getStationNameByCustomerCodeAndCabinetCode(customerCode, cabinetCode);
    }
}

mapper xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.yto.dao.MdmScsInfoDao">
    <select id="getStationNameByCabinetCode" resultType="string">
    SELECT
        station_name
    FROM
        t_scs_info
    WHERE
        cabinet_code = #{cabinetCode}
    ORDER BY
        create_time DESC
    LIMIT 1
    </select>

    <select id="getStationNameByCustomerCodeAndCabinetCode" resultType="string">
    SELECT
       station_name
    FROM
        t_scs_info
    WHERE
        customer_code = #{customerCode}
        AND cabinet_code = #{cabinetCode}
    ORDER BY
        create_time DESC
    LIMIT 1
    </select>
</mapper>
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐