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)

总结

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

相关文章

  • Idea 编译并运行 Spark 3.1.1 源码的方法

    Idea 编译并运行 Spark 3.1.1 源码的方法

    这篇文章主要介绍了Idea 编译并运行 Spark 3.1.1源码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • Java读取 Word 文本框中的文本和图片的实践指南

    Java读取 Word 文本框中的文本和图片的实践指南

    Spire.Doc for Java 是一个功能强大的Word文档处理库,它允许开发者在Java应用程序中创建、读取、写入、转换和打印Word文档,下面我们就来看看如何使用Spire.Doc for Java读取 Word 文本框中的文本和图片吧
    2025-11-11
  • MyBatis中ResultMap与多表查询的处理方法

    MyBatis中ResultMap与多表查询的处理方法

    这篇文章主要介绍了MyBatis中ResultMap与多表查询的处理方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • 基于Java类的加载方式

    基于Java类的加载方式

    这篇文章主要介绍了基于Java类的加载方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java杂谈之如何消除代码中一大串参数列表

    Java杂谈之如何消除代码中一大串参数列表

    参数列表和字面意思差不多,主要是表示该参数数量不是固定的,可能会有一个参数,可能多个,不管多少个参数,都放到一个数组处理,这种参数叫可变参数。可变长参数要放在最后一个参数位置处理,但是一个函数里面不能有俩种类型的可变参数
    2021-10-10
  • Java SpringBoot高级用法详解

    Java SpringBoot高级用法详解

    这篇文章主要为大家详细介绍了Java Spring Boot的一些高级用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-09-09
  • Java与C++分别用递归实现汉诺塔详解

    Java与C++分别用递归实现汉诺塔详解

    汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。本文将用Java与C++分别实现,感兴趣的可以学习一下
    2022-05-05
  • java中实现视频处理以及播放功能代码详解

    java中实现视频处理以及播放功能代码详解

    这篇文章主要给大家介绍了关于java中实现视频处理以及播放功能的相关资料,最近要实现一套音视频播放程序,所以这里给大家总结下,需要的朋友可以参考下
    2023-09-09
  • IDEA 格式化SQL代码技巧分享

    IDEA 格式化SQL代码技巧分享

    这篇文章主要介绍了IDEA 格式化SQL代码技巧分享,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java求解二叉树的最近公共祖先实例代码

    Java求解二叉树的最近公共祖先实例代码

    树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合,这篇文章主要给大家介绍了关于Java求解二叉树的最近公共祖先的相关资料,需要的朋友可以参考下
    2021-06-06

最新评论