IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> mybatis-plus接入多数据源 -> 正文阅读

[Java知识库]mybatis-plus接入多数据源

需求

?我所在项目的代码要接入当前数据库所在的服务器下的另外一个数据库的一张表,所以我这个springboot项目要接入同一个服务器下的两个不同的数据库

推荐博客:?

官方文档:多数据源 | MyBatis-Plus (baomidou.com)

Mybatis | Mybatis-plus配置多数据源,连接多数据库_Cz范特西的博客-CSDN博客_mybatis-plus配置多数据源

MyBatisPlus--多数据源_杼蛘的博客-CSDN博客_mybatisplus多数据源?

接入过程

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

?附注:

我的操作相当于在一个service里,先从从数据库的一张表里查出数据,然后再把数据进行处理插入到主数据库的一张表里,因为项目里业务是定时任务,所以我直接在定时任务里进行两个数据源的操作

主数据库JdyInfoMapper

package cn.mn.ac.eff.mapper;

import cn.mn.ac.core.mp.base.BaseMapper;
import cn.mn.ac.eff.entity.JdyInfo;

public interface JdyMapper extends BaseMapper<JdyInfo> {
}

主数据库JdyInfoService

package cn.mn.ac.eff.service;

import cn.mn.ac.core.mp.base.BaseServiceImpl;
import cn.mn.ac.eff.entity.JdyInfo;
import cn.mn.ac.eff.mapper.JdyMapper;
import org.springframework.stereotype.Service;

@Service
public class JdyInfoService extends BaseServiceImpl<JdyMapper, JdyInfo> {
}

?主数据库JdyInfo.class

package cn.mn.ac.eff.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("jdy_info")
public class JdyInfo implements Serializable {

    @TableId(value = "id", type = IdType.AUTO)
    private String id;
    private String dataId;
    private String formName;
    private String number;
    private String requireNo;
    private String userName;
    private String secondaryDept;
    private String deptName;
    private String requireType;
    private String reqAcceptorEst;
    private String reqAcceptorNumber;
    private String reqAcceptorName;
    private String reqAcceptorDept;
    private String chargeType;
    private double requireBudget;
    private String isNeedOuter;
    private String innerDays;
    private String dueItem;
    private double dueStartMoney;
    private double dueEndMoney;
    private double totalMoney;
    private String formula;
    private double remainMoney;
    private String conclusion;
    private String requireWay;
    private Integer flowStatus;
    private String flowStatusName;
    private Date createTime;
    private Date updateTime;
    private String creator;
    private String updater;
}

IterpJdyInfo.Mapper=====>从数据库一张表的mapper

package cn.mn.ac.eff.mapper;

import cn.mn.ac.core.mp.base.BaseMapper;
import cn.mn.ac.eff.entity.IterpJdyInfo;

public interface IterpJdyMapper extends BaseMapper<IterpJdyInfo> {
}

?从数据库IterpJdyInfoService

package cn.mn.ac.eff.service;

import cn.mn.ac.core.mp.base.BaseServiceImpl;
import cn.mn.ac.eff.entity.IterpJdyInfo;
import cn.mn.ac.eff.mapper.IterpJdyMapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;

@Service
@DS("second")
public class IterpJdyService extends BaseServiceImpl<IterpJdyMapper, IterpJdyInfo> {
}

从数据库IterpJdyInfo.clas

package cn.mn.ac.eff.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("record_list")
public class IterpJdyInfo implements Serializable {

    private static final long serialVersionUID = -4788457616802723223L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private Integer source;
    private String event;
    private String recordId;
    private Long createTime;
    private String content;
}

?Job======>定时任务【直接对两个数据源进行操作,这里不能直接使用两个数据源的service】

package cn.mn.ac.eff.schedule.jobs;

import cn.mn.ac.core.tool.jackson.JsonUtil;
import cn.mn.ac.core.tool.utils.*;
import cn.mn.ac.eff.constant.CommonAttributeConstant;
import cn.mn.ac.eff.constant.CommonSql;
import cn.mn.ac.eff.entity.IterpJdyInfo;
import cn.mn.ac.eff.entity.JdyInfo;
import cn.mn.ac.eff.mapper.IterpJdyMapper;
import cn.mn.ac.eff.mapper.JdyMapper;
import cn.mn.ac.eff.model.JdyReqData;
import cn.mn.ac.eff.schedule.TaskJob;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionException;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 从iterp系统同步简道云数据job
 */
@Slf4j
public class SyncIterpJdyJob extends TaskJob {

    private final IterpJdyMapper iterpJdyMapper = SpringUtil.getBean(IterpJdyMapper.class);
    private final JdyMapper jdyMapper = SpringUtil.getBean(JdyMapper.class);

    @Override
    protected void runJob(JobDataMap dataMap, List<String> errors) throws JobExecutionException {
        try {
        log.info("sync iterp jdy job start.");

        DynamicDataSourceContextHolder.push("second");   //操作从数据库
        String iterpJdySql = CommonSql.iterp_jdy_sql();
        List<IterpJdyInfo> iterpJdyInfos = iterpJdyMapper.selectList(Wrappers.lambdaQuery(IterpJdyInfo.class)
                .inSql(IterpJdyInfo::getId, iterpJdySql));  //从数据库IterpJdyInfo表查询操作
        DynamicDataSourceContextHolder.poll();   //关闭从数据库
        DynamicDataSourceContextHolder.push("master");  //操作主数据库,进行主数据库中的JdyInfo表入库操作
        List<JdyReqData> jdyReqDataList = iterpJdyInfos.stream().map(ele -> {
            JsonNode resBodyRelate = JsonUtil.readTree(ele.getContent());
            JdyReqData res = JsonUtil.parse(resBodyRelate.get("data").toString(), JdyReqData.class);
            res.setDataId(ele.getRecordId());
            return res;
        }).collect(Collectors.toList());
        List<JdyInfo> jdyInfos = jdyMapper.selectList(Wrappers.lambdaQuery(JdyInfo.class));
        List<String> jdyRequireNos = jdyInfos.stream().map(JdyInfo::getRequireNo).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<String> removeRequireNos = jdyReqDataList.stream().filter(ele -> ele != null)
                .filter(ele -> jdyRequireNos.contains(ele.getRequireNo()))
                .filter(ele -> ele.getSecondaryDept() != null && StringUtil.isNotBlank(ele.getSecondaryDept().getName()))
                .map(JdyReqData::getRequireNo).collect(Collectors.toList());
        List<JdyInfo> jdyInfoList = jdyReqDataList.stream().filter(ele -> ele != null)
                .filter(ele -> {
                    if (jdyRequireNos.contains(ele.getRequireNo()) && (ele.getSecondaryDept() == null || StringUtil.isBlank(ele.getSecondaryDept().getName())))
                        return false;
                    return true;
                }).map(ele -> {
                    JdyInfo jdyInfo = BeanUtil.copy(ele, JdyInfo.class);
                    jdyInfo.setUserName(ele.getUserInfo() != null ? ele.getUserInfo().getName() : "");
                    jdyInfo.setCreator(ele.getCreator() != null ? ele.getCreator().getName() : "");
                    jdyInfo.setUpdater(ele.getUpdater() != null ? ele.getUpdater().getName() : "");
                    jdyInfo.setDeptName(ele.getDeptInfo() != null ? ele.getDeptInfo().getName() : "");
                    jdyInfo.setFlowStatus(ele.getFlowStatus() != null ? Integer.valueOf(ele.getFlowStatus()) : null);
                    if (ele.getFlowStatus() != null)
                        jdyInfo.setFlowStatusName(CommonAttributeConstant.FLOWSTATUSMAP.getOrDefault(Integer.valueOf(ele.getFlowStatus()), ""));
                    jdyInfo.setCreateTime(ele.getCreateTime());
                    jdyInfo.setUpdateTime(ele.getUpdateTime());
                    jdyInfo.setReqAcceptorDept(ele.getReqAcceptorDept() != null ? ele.getReqAcceptorDept().getName() : "");
                    jdyInfo.setReqAcceptorEst(ele.getReqAcceptorEst() != null ? ele.getReqAcceptorEst().getName() : "");
                    jdyInfo.setReqAcceptorName(ele.getReqAcceptorName() != null ? ele.getReqAcceptorName().getName() : "");
                    jdyInfo.setSecondaryDept(ele.getSecondaryDept() == null ? "" : ele.getSecondaryDept().getName());
                    return jdyInfo;
                }).collect(Collectors.toList());
        jdyMapper.delete(Wrappers.lambdaQuery(JdyInfo.class).in(JdyInfo::getRequireNo, removeRequireNos));
        jdyMapper.insertBatch(jdyInfoList);
        DynamicDataSourceContextHolder.poll();  //关闭操作主数据库
        log.info("sync iterp jdy job end.");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            errors.add(Exceptions.unwrap(e).getMessage());
        }
    }
}

?配置中心使用的是nacos,关于多数据源的配置如下

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 
    database: 3
  datasource:
    dynamic: 
      primary: master
      strict: false
      datasource:
        master:     //主数据库
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/eff_sys?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
          username: root
          password: root
          druid:
            max-active: 100
        second:     //从数据库
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/iterp?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
          username: root
          password: root
          druid:
            max-active: 100

建议:

建议可以看一下我这篇文章推荐博客的第一个博客,讲得很详细?

PS:事务我没测是不是可以同时处理啊

小白一枚,大神绕行

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 17:56:45  更:2022-06-25 18:00:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:32:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码