Mybatis使用@DS配置多数据源

时间:2025-02-11 07:47:05

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

Maven jar包

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

配置文件配置

数据源配置

=smdm
-class-name=
=jdbc:mysql://10.130.16.185:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
=test
=123456
-size=5
-active=30
-idle=1
-wait=6000
-query=SELECT 1
-on-borrow=true
-on-return=false
-while-idle=true

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

使用@DS注解代码

使用@DS说明

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

#默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页
=true
# 会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,
# 设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定
=true
#分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询
=true
# druid数据源默认开启了自带的管理界面,如不需要则直接配置关闭即可
=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 "-////DTD Mapper 3.0//EN" "/dtd/" >
<mapper namespace="">
    <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>