MybatisPlus中如何調(diào)用Oracle存儲過程
起因
由于需要將新數(shù)據(jù)同步到另外的數(shù)據(jù)庫,所以需要使用dblink
進(jìn)行操作,但是dblink不支持寫入操作,因此需要調(diào)用寫好的存儲過程才能實(shí)現(xiàn)將新數(shù)據(jù)插入新數(shù)據(jù)的同時插入舊數(shù)據(jù)庫。
準(zhǔn)備工作
預(yù)先準(zhǔn)備好新舊兩個數(shù)據(jù)庫
舊的數(shù)據(jù)庫
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) )
新的數(shù)據(jù)庫
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) )
對應(yīng)的實(shí)體為:
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("新數(shù)據(jù)庫對應(yīng)實(shí)體") @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 = "刪除標(biāo)志", hidden = true) @TableField(fill = FieldFill.INSERT) @TableLogic private Boolean deleted; @ApiModelProperty("用戶賬號") private String account; @ApiModelProperty("用戶名稱") private String username; @ApiModelProperty("密碼") private String password; @ApiModelProperty("插入舊數(shù)據(jù)庫返回的id") @TableField(exist = false) private Integer oldUserId; }
創(chuàng)建存儲過程
創(chuàng)建一個存儲過程用于將新數(shù)據(jù)庫的數(shù)據(jù)字段和舊的數(shù)據(jù)庫字段映射上,同時使用序列自增作為id值,將新數(shù)據(jù)插入舊數(shù)據(jù)庫中。
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進(jìn)行判斷 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('添加到舊數(shù)據(jù)庫賬號成功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í)行存儲過程和函數(shù)的--> <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>
注意點(diǎn):
- statementType 設(shè)置為 CALLABLE
- 在存儲過程中使用參數(shù)時,除了寫上必要的屬性名外,還必須指定參數(shù)的 mode(模式),可選值為 IN、OUT、INOUT 三種,入?yún)⑹褂?IN,出參使用 OUT,輸入輸出參數(shù)使用 INOUT。
- OUT 模式的參數(shù),必須指定 jdbcType。因?yàn)樵?IN 模式下,MyBatis 提供了默認(rèn)的 jdbcType,在 OUT 模式下沒有提供,因此必須指定 jdbcType
- 當(dāng)入?yún)⒋嬖跓o法識別,執(zhí)行報錯時,最好指定 jdbcType
創(chuàng)建mapper接口
@Mapper @Repository public interface NewUserMapper extends BaseMapper<NewUser> { /** * * 將新數(shù)據(jù)新增的賬號插入舊數(shù)據(jù)庫 * @author donlex * @param req */ void insertIntoOldUser(NewUser req); }
這里定義的是void
方法,但是實(shí)際上是會返回NewUser
實(shí)體對象,所以可以通過get方法獲取屬性值,這就是為什么在實(shí)體中定義了一個oldUserId
,但是它不是數(shù)據(jù)表中真實(shí)存在的字段 @TableField(exist = false)
創(chuàng)建controller方法
這里為了方便就直接在controller
中寫方法調(diào)用了。
import lombok.extern.slf4j.Slf4j; @Slf4j @RestController public class SysUserController { @Autowired private NewUserMapper newUserMapper; @ApiOperation("將新數(shù)據(jù)寫入舊數(shù)據(jù)庫中") @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)
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MybatisPlus為何可以不用@MapperScan詳解
這篇文章主要給大家介紹了關(guān)于MybatisPlus為何可以不用@MapperScan的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用MybatisPlus具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-04-04利用consul在spring boot中實(shí)現(xiàn)分布式鎖場景分析
這篇文章通過場景分析給大家介紹如何利用consul在spring boot中實(shí)現(xiàn)簡單的分布式鎖功能,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-09-09Java靜態(tài)方法和實(shí)例方法區(qū)別詳解
這篇文章主要為大家詳細(xì)介紹了Java靜態(tài)方法和實(shí)例方法的區(qū)別,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12Spring ApplicationListener監(jiān)聽器用法詳解
這篇文章主要介紹了Spring ApplicationListener監(jiān)聽器用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解
這篇文章主要為大家介紹了SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12