楼主: zhanghaibin卍
56 0

[作业] springboot3.5.7使用多数据源 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-4-11
最后登录
2018-4-11

楼主
zhanghaibin卍 发表于 2025-11-24 12:19:41 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

1、在项目中添加相关依赖,修改 pom.xml 文件以引入所需组件。

<!-- 动态数据源依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.6.1</version>
</dependency>

2、配置 application.yml 文件,设置多数据源的相关参数。

spring:
  datasource:
    dynamic:
      primary: primary  # 指定默认数据源
      datasource:
        # 第一个数据源(默认)
        primary:
          url: jdbc:mysql://127.0.0.1:22377/dade_py?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          hikari:
            maximum-pool-size: 20
            minimum-idle: 5
            connection-timeout: 30000
            idle-timeout: 600000
        # 第二个数据源
        second:
          url: jdbc:mysql://【第二个数据库IP】:【端口】/【数据库名】?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
          username: 【第二个数据库用户名】
          password: 【第二个数据库密码】
          driver-class-name: com.mysql.cj.jdbc.Driver
          hikari:
            maximum-pool-size: 15
            minimum-idle: 3
            connection-timeout: 30000
            idle-timeout: 600000

3、通过注解方式实现数据源的切换。只需在 Service 类或具体方法上使用 @DS 注解,即可指定对应的数据源。

import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    // 使用默认数据源(primary)
    public void testPrimaryDb() {
        // ... 操作默认数据库
    }

    // 切换到第二个数据源(second)
    @DS("second")
    public void testSecondDb() {
        // ... 操作第二个数据库
    }
}

4、若希望整个 Service 类中的所有方法均使用同一数据源,可将 @DS 注解直接标注在类上。

@Service
@DS("second") // ???? 类上注解:该类所有方法默认使用 second 数据源
public class SecondDbService {

    private final UserMapper userMapper;

    public SecondDbService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    // 无需单独加注解,自动使用 second 数据源
    public List<User> getUserList() {
        return userMapper.selectList(null);
    }
}

5、当某个 Service 方法需要同时访问多个数据源时(例如从 primary 数据源查询数据,并插入到 second 数据源),仅使用 @DS 注解无法满足需求。此时需借助 DynamicDataSourceContextHolder 手动管理数据源上下文切换。

@Service
public class DataSyncService {

    private final UserMapper userMapper;
    private final OrderMapper orderMapper;

    public DataSyncService(UserMapper userMapper, OrderMapper orderMapper) {
        this.userMapper = userMapper;
        this.orderMapper = orderMapper;
    }

    public void syncData() {
        // 1. 用默认数据源(primary)查询数据
        List<User> userList = userMapper.selectList(null);

        // 2. 手动切换到 second 数据源(try-finally 确保切换后恢复)
        DynamicDataSourceContextHolder.push("second");
        try {
            // 执行 SQL:使用 second 数据源
            orderMapper.batchInsert(userList); 
        } finally {
            // 3. 恢复默认数据源(必须执行,避免污染上下文)
            DynamicDataSourceContextHolder.poll();
        }
    }
}

6、关于 Mapper 接口的设计:每个 Mapper 应固定绑定一个数据源。若涉及两个数据库,则应分别创建两个独立的 Mapper 接口。

默认数据源对应的 Mapper 配置如下:

package com.dao;

import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

/**
* 使用默认数据源
* */
@DS("primary")
@Mapper
public interface CommonMapper {
    @Select("${sql}")
    public List<Map<String,Object>> query(@Param("sql")String sql);

    @Select("${sql}")
    public String querycode(@Param("sql")String sql);

    @Insert("${sql}")
    public int insert(@Param("sql")String sql);

    @Update("${sql}")
    public Integer update(@Param("sql")String sql);

    @Delete("${sql}")
    public Boolean del(@Param("sql")String sql);

    /**
     * LAST_INSERT_ID()
     * 客户端返回的值是该客户端产生对影响AUTO_INCREMENT列的最新语句第一个 AUTO_INCREMENT值的。这个值不能被其它客户端影响,即使它们产生它们自己的 AUTO_INCREMENT值。这个行为保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁或处理
     * */
    @Select("SELECT LAST_INSERT_ID()")
    public int id();

    /**
     * 开启事务
     * */
    @Select("START TRANSACTION")
    public Boolean TRANSACTION();

    /**
     * 提交事务
     * */
    @Select("COMMIT")
    public Boolean COMMIT();

    /**
     * 回滚事务
     * */
    @Select("ROLLBACK")
    public Boolean ROLLBACK();
}

另一个数据源的 Mapper 配置示例如下:

package com.dao;

import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

/**
* 使用second数据源
* */
@DS("second")
@Mapper
public interface CommonSecondMapper {
    @Select("${sql}")
    public List<Map<String,Object>> query(@Param("sql")String sql);

    @Select("${sql}")
    public String querycode(@Param("sql")String sql);

    @Insert("${sql}")
    public int insert(@Param("sql")String sql);

    @Update("${sql}")
    public Integer update(@Param("sql")String sql);

    @Delete("${sql}")
    public Boolean del(@Param("sql")String sql);

    /**
     * LAST_INSERT_ID()
     * 客户端返回的值是该客户端产生对影响AUTO_INCREMENT列的最新语句第一个 AUTO_INCREMENT值的。这个值不能被其它客户端影响,即使它们产生它们自己的 AUTO_INCREMENT值。这个行为保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁或处理
     * */
    @Select("SELECT LAST_INSERT_ID()")
    public int id();

    /**
     * 开启事务
     * */
    @Select("START TRANSACTION")
    public Boolean TRANSACTION();

    /**
     * 提交事务
     * */
    @Select("COMMIT")
    public Boolean COMMIT();

    /**
     * 回滚事务
     * */
    @Select("ROLLBACK")
    public Boolean ROLLBACK();
}

实际使用时的调用方式如下所示:

package com.service.impl;

import com.dao.CommonMapper;
import com.dao.CommonSecondMapper;
import com.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private CommonSecondMapper commonSecondMapper;

    @Override
    public List<Map<String,Object>> query(String table, Map<String, Object> params) {
        List<Map<String,Object>> datas = commonMapper.query("select * from dade");
        List<Map<String,Object>> user = commonSecondMapper.query("select * from users");
        System.out.println(datas);
        System.out.println(user);
        return datas;
    }
}
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Spring Pring boot RING ING

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-25 03:55