MybatisPlus中如何調(diào)用Oracle存儲(chǔ)過程
起因
由于需要將新數(shù)據(jù)同步到另外的數(shù)據(jù)庫(kù),所以需要使用dblink進(jìn)行操作,但是dblink不支持寫入操作,因此需要調(diào)用寫好的存儲(chǔ)過程才能實(shí)現(xiàn)將新數(shù)據(jù)插入新數(shù)據(jù)的同時(shí)插入舊數(shù)據(jù)庫(kù)。
準(zhǔn)備工作
預(yù)先準(zhǔn)備好新舊兩個(gè)數(shù)據(jù)庫(kù)
舊的數(shù)據(jù)庫(kù)
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ù)庫(kù)
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) )
對(duì)應(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ù)庫(kù)對(duì)應(yīng)實(shí)體")
@KeySequence("s_old_user")
public class NewUser {
@ApiModelProperty("主鍵")
@TableId(type = IdType.INPUT)
private Long id;
@ApiModelProperty(value = "創(chuàng)建時(shí)間", hidden = true)
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@ApiModelProperty(value = "更新時(shí)間", 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("用戶賬號(hào)")
private String account;
@ApiModelProperty("用戶名稱")
private String username;
@ApiModelProperty("密碼")
private String password;
@ApiModelProperty("插入舊數(shù)據(jù)庫(kù)返回的id")
@TableField(exist = false)
private Integer oldUserId;
}創(chuàng)建存儲(chǔ)過程
創(chuàng)建一個(gè)存儲(chǔ)過程用于將新數(shù)據(jù)庫(kù)的數(shù)據(jù)字段和舊的數(shù)據(jù)庫(kù)字段映射上,同時(shí)使用序列自增作為id值,將新數(shù)據(jù)插入舊數(shù)據(jù)庫(kù)中。
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ù)庫(kù)賬號(hào)成功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í)行存儲(chǔ)過程和函數(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
- 在存儲(chǔ)過程中使用參數(shù)時(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法識(shí)別,執(zhí)行報(bào)錯(cuò)時(shí),最好指定 jdbcType
創(chuàng)建mapper接口
@Mapper
@Repository
public interface NewUserMapper extends BaseMapper<NewUser> {
/**
*
* 將新數(shù)據(jù)新增的賬號(hào)插入舊數(shù)據(jù)庫(kù)
* @author donlex
* @param req
*/
void insertIntoOldUser(NewUser req);
}這里定義的是void方法,但是實(shí)際上是會(huì)返回NewUser實(shí)體對(duì)象,所以可以通過get方法獲取屬性值,這就是為什么在實(shí)體中定義了一個(gè)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ù)庫(kù)中")
@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é)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MybatisPlus為何可以不用@MapperScan詳解
這篇文章主要給大家介紹了關(guān)于MybatisPlus為何可以不用@MapperScan的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MybatisPlus具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-04-04
利用consul在spring boot中實(shí)現(xiàn)分布式鎖場(chǎng)景分析
這篇文章通過場(chǎng)景分析給大家介紹如何利用consul在spring boot中實(shí)現(xiàn)簡(jiǎn)單的分布式鎖功能,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-09-09
java騰訊AI人臉對(duì)比對(duì)接代碼實(shí)例
這篇文章主要介紹了java騰訊AI人臉對(duì)比對(duì)接,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
Java靜態(tài)方法和實(shí)例方法區(qū)別詳解
這篇文章主要為大家詳細(xì)介紹了Java靜態(tài)方法和實(shí)例方法的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Spring ApplicationListener監(jiān)聽器用法詳解
這篇文章主要介紹了Spring ApplicationListener監(jiān)聽器用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解
這篇文章主要為大家介紹了SpringBoot返回結(jié)果統(tǒng)一處理實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Scheduler定時(shí)任務(wù)調(diào)度詳解
文章介紹了SysJobServiceImpl類中定時(shí)任務(wù)調(diào)度的相關(guān)方法,包括清除、檢查存在性、創(chuàng)建、暫停、恢復(fù)、刪除任務(wù),以及觸發(fā)任務(wù),并提到了JobKey、CronUtils、ScheduleUtils、SpringUtils等工具類的使用,適用于Spring管理環(huán)境2025-01-01

