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 = "創(chuàng)建時間", 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; }
創(chuàng)建存儲過程
創(chuàng)建一個存儲過程用于將新數據庫的數據字段和舊的數據庫字段映射上,同時使用序列自增作為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;
創(chuàng)建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是執(zhí)行存儲過程和函數的--> <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
- 當入參存在無法識別,執(zhí)行報錯時,最好指定 jdbcType
創(chuàng)建mapper接口
@Mapper @Repository public interface NewUserMapper extends BaseMapper<NewUser> { /** * * 將新數據新增的賬號插入舊數據庫 * @author donlex * @param req */ void insertIntoOldUser(NewUser req); }
這里定義的是void
方法,但是實際上是會返回NewUser
實體對象,所以可以通過get方法獲取屬性值,這就是為什么在實體中定義了一個oldUserId
,但是它不是數據表中真實存在的字段 @TableField(exist = false)
創(chuàng)建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()) } }
執(zhí)行的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)
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MybatisPlus為何可以不用@MapperScan詳解
這篇文章主要給大家介紹了關于MybatisPlus為何可以不用@MapperScan的相關資料,文中通過圖文介紹的非常詳細,對大家學習或者使用MybatisPlus具有一定的參考學習價值,需要的朋友可以參考下2023-04-04利用consul在spring boot中實現分布式鎖場景分析
這篇文章通過場景分析給大家介紹如何利用consul在spring boot中實現簡單的分布式鎖功能,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-09-09Spring ApplicationListener監(jiān)聽器用法詳解
這篇文章主要介紹了Spring ApplicationListener監(jiān)聽器用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-11-11