MybatisPlus中如何调用Oracle存储过程

 更新时间:2023年05月26日 15:01:14   作者:DonLex  
这篇文章主要介绍了MybatisPlus中如何调用Oracle存储过程的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

起因

由于需要将新数据同步到另外的数据库,所以需要使用dblink进行操作,但是dblink不支持写入操作,因此需要调用写好的存储过程才能实现将新数据插入新数据的同时插入旧数据库。

准备工作

预先准备好新旧两个数据库

旧的数据库

create table OLD_USER
(
  USER_ID                    NUMBER(6) not null primary key,
  LOGIN_NAME                 VARCHAR2(100) not null,
  REAL_NAME                  VARCHAR2(300),
  PASSWORD                   CHAR(64)
)

新的数据库

create table NEW_USER
(
  ID            NUMBER(11) not null primary key,
  CREATE_TIME   TIMESTAMP(6),
  UPDATE_TIME   TIMESTAMP(6),
  DELETED       NUMBER(1),
  ACCOUNT       VARCHAR2(255),
  USERNAME      VARCHAR2(255),
  PASSWORD      VARCHAR2(255)
)

对应的实体为:

package com.donlex.demo.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.Date;
import java.util.List;
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel("新数据库对应实体")
@KeySequence("s_old_user")
public class NewUser {
    @ApiModelProperty("主键")
    @TableId(type = IdType.INPUT)
    private Long id;
    @ApiModelProperty(value = "创建时间", hidden = true)
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @ApiModelProperty(value = "更新时间", hidden = true)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    @ApiModelProperty(value = "删除标志", hidden = true)
    @TableField(fill = FieldFill.INSERT)
    @TableLogic
    private Boolean deleted;
    @ApiModelProperty("用户账号")
    private String account;
    @ApiModelProperty("用户名称")
    private String username;
    @ApiModelProperty("密码")
    private String password;
    @ApiModelProperty("插入旧数据库返回的id")
    @TableField(exist = false)
    private Integer oldUserId;
}

创建存储过程

创建一个存储过程用于将新数据库的数据字段和旧的数据库字段映射上,同时使用序列自增作为id值,将新数据插入旧数据库中。

create or replace procedure PRO_TO_OLD_USER(
                                         v_account in varchar2,
                                         v_username in varchar2,
                                         v_password in varchar2,
                                         v_result out varchar2) is
  V_ID number;
  PRAGMA AUTONOMOUS_TRANSACTION;
begin
-- 使用序列自增做为主键,s_old_user为序列名, @dklinkName 是dblink名
  SELECT s_old_user.NEXTVAL @dklinkName into V_ID FROM DUAL;
  insert into OLD_USER(USER_ID,
                        LOGIN_NAME,
                        REAL_NAME,
                        PASSWORD
                      )
  VALUES (V_ID,
-- 使用case进行判断 v_account 字段是否为空
          case when v_account is null
                 then
                 '空'
               else
                 v_account
          end,
          v_username,
          v_password
        );
  commit;
-- 返回自增的序列值
  v_result := V_ID;
  DBMS_OUTPUT.put_line('添加到旧数据库账号成功ID为' || V_ID);
end PRO_TO_OLD_USER;

创建mapper中的方法

<?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="com.donlex.demo.mapper.NewUserMapper">
 <!-- statementType 声明指向的是什么类型,其中CALLABLE是执行存储过程和函数的-->
 <select id="insertIntoOldUser" statementType="CALLABLE" parameterType="com.donlex.demo.entity.NewUser">
    {call PRO_TO_OLD_USER
         (
             #{account,mode=IN},
             #{username,mode=IN},
             #{password,mode=IN},
             #{oldUserId,mode=OUT,jdbcType=INTEGER}
         )
    }
  </select>
</mapper>

注意点:

  • statementType 设置为 CALLABLE
  • 在存储过程中使用参数时,除了写上必要的属性名外,还必须指定参数的 mode(模式),可选值为 IN、OUT、INOUT 三种,入参使用 IN,出参使用 OUT,输入输出参数使用 INOUT。
  • OUT 模式的参数,必须指定 jdbcType。因为在 IN 模式下,MyBatis 提供了默认的 jdbcType,在 OUT 模式下没有提供,因此必须指定 jdbcType
  • 当入参存在无法识别,执行报错时,最好指定 jdbcType

创建mapper接口

@Mapper
@Repository
public interface NewUserMapper extends BaseMapper<NewUser> {
  /**
   * 
   * 将新数据新增的账号插入旧数据库
   * @author donlex
   * @param req
   */
  void insertIntoOldUser(NewUser req);
}

这里定义的是void方法,但是实际上是会返回NewUser实体对象,所以可以通过get方法获取属性值,这就是为什么在实体中定义了一个oldUserId,但是它不是数据表中真实存在的字段 @TableField(exist = false)

创建controller方法

这里为了方便就直接在controller中写方法调用了。

import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class SysUserController {
    @Autowired
    private NewUserMapper newUserMapper;
    @ApiOperation("将新数据写入旧数据库中")
    @PostMapping("/test")
    public Boolean addNewUserToOldUser(NewUser newUser){
        newUserMapper.insertIntoNewUser(newsUser);
        log.info("oldUserId为{}",newUser.getOldUserId())
    }
}

执行的debug日志

2019-12-30 15:58:31.850 DEBUG  ==>  Preparing: {call PRO_TO_OLD_USER ( ?, ?, ?, ? ) } 

2019-12-30 15:58:31.885 DEBUG  ==>  Parameters: 357869(String), donlex(String), a493fe7c29ce(String), 0(Integer)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一篇文章搞定Struts2的类型转换

    一篇文章搞定Struts2的类型转换

    这篇文章主要介绍了关于Struts2类型转换的相关资料,文中主要介绍了Struts2的类型转换器和自定义类型转换器的实现,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • Java基础之String类使用与字符串比较

    Java基础之String类使用与字符串比较

    String类代表字符串,java程序中的所有字符串文字(例如"abc")都被实现为此类的实例。本文将详解String类的使用,以及如何进行字符串比较
    2022-08-08
  • Java多线程ThreadAPI详细介绍

    Java多线程ThreadAPI详细介绍

    这篇文章主要介绍了Java多线程ThreadAPI详细介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java深入讲解AWT实现事件处理流程

    Java深入讲解AWT实现事件处理流程

    AWT的事件处理是一种委派式事件处理方式:普通组件(事件源)将整个事件处理委托给特定的对象(事件监听器);当该事件源发生指定的事件时,就通知所委托的事件监听器,由事件监听器来处理这个事件
    2022-04-04
  • Druid连接池的自定义过滤功能实现方法

    Druid连接池的自定义过滤功能实现方法

    在数据密集型应用中,监控和分析数据库操作对于确保性能和稳定性至关重要,本文将探讨如何实现一个自定义的Druid过滤器来捕获数据库请求并进行日志记录,以辅助开发和维护工作,需要的朋友可以参考下
    2023-11-11
  • Java应该在哪里判断List是否为空

    Java应该在哪里判断List是否为空

    在Java中,我们常用List来存储数据,但是我们怎么判断它是否成功带来了我们需要的数据呢?下面这篇文章主要给大家介绍了关于Java应该在哪里判断List是否为空的相关资料,需要的朋友可以参考下
    2022-02-02
  • mybatis的动态SQL以及连接池详解

    mybatis的动态SQL以及连接池详解

    这篇文章主要介绍了mybatis的动态SQL以及连接池详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • java split结果去除空字符串的方法实现

    java split结果去除空字符串的方法实现

    在Java开发中,我们经常需要对字符串进行分割操作,本文主要介绍了java split结果去除空字符串的方法实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • Flutter瀑布流仿写原生的复用机制详解

    Flutter瀑布流仿写原生的复用机制详解

    这篇文章主要给大家介绍了关于Flutter瀑布流仿写原生的复用机制的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用flutter具有一定的参考学习价值,需要的朋友可以参考下
    2021-07-07
  • SpringBoot如何返回Json数据格式

    SpringBoot如何返回Json数据格式

    这篇文章主要介绍了SpringBoot如何返回Json数据格式问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论