SpringBoot中使用Mybatis调用Oracle存储过程

SpringBoot中使用Mybatis调用Oracle存储过程

1. 添加Maven依赖

<!-- 我的环境为: oracle数据库11g,jdk1.8 -->
<!-- mybaits plus 插件 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>
<!-- Oracle连接驱动 -->
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.3</version>
</dependency>

2. Yaml中配置好Db、Mybatis相关配置

# 比如Oracle连接配置:   
spring:
	datasource:
		url: jdbc:oracle:thin:@127.0.0.1:1521/orcl
		username: system
		password: 123456
		driver-class-name: oracle.jdbc.OracleDriver
# 比如Mybatis相关配置
# 	配置mysqlplus生成的Sql打印到控制台,用于观察Sql的实际情况
# 	mybatis-plus:
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus: # 配置mybaitis-plus,关闭自动驼峰命名规则映射
  configuration:
    map-underscore-to-camel-case: false
  # 配置Mybatis-Plus自定义分Mappe.xml路径
  mapper-locations: classpath*:/mapper/**/*.xml
  # 配置entity实体对象的包路径,这样mapper.xml可以不用带包名
  type-aliases-package: com.mediinfo.entity
# 配置全局的实体类ID生成策略 ,插入数据时,ID自增  Oracle通过序列策略,此处无需开启
#  global-config:
#    db-config:
#      id-type: auto

3. 测试的 entity实体类

// gy_brjbxxk 表结构,这里就不创建了,参考下方实体的属性,随便建两个字段,就可以模拟出来啦
@SuppressWarnings("serial")
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("人员信息")
public class GyBrjbxxk extends Model<GyBrjbxxk> {
    /* 就诊卡号 */
    @TableId(value = "JZKH")
    @ApiModelProperty(value = "就诊卡号")
    private String jzkh;
    /* 姓名 */
    @ApiModelProperty(value = "姓名")
    private String xm;
    /* 性别 */
    @ApiModelProperty(value = "性别")
    private String xb;
   
    /**
     * 获取主键值
     *
     * @return 主键值
     */
    @Override
    protected Serializable pkVal() {
        return this.jzkh;
    }
}

4. Mapper(Dao)接口

@Mapper
public interface GyBrjbxxkDao extends BaseMapper<GyBrjbxxk> {

    // 调用oracle存储过程返回单个结果集
    void findDeptNameById(Map<String,Object> map);

    // 调用oracle存储过程返回多个结果集
    void findAllDeptProcedure(Map<String,Object> map);
}

5. GyBrjbxxkDao.xml

<?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.mediinfo.dao.GyBrjbxxkDao">
	<!-- 返回多个结果集时,该resultMap必须声明,参考下方 id="findAllDeptProcedure"的方法
			若result中的column名和Db字段名一致,标签内部的匹配可不写,因同名会自动映射 -->
    <resultMap id="deptResultMap" type="com.mediinfo.entity.GyBrjbxxk">
<!--        <id column="jzkh" property="jzkh"/>-->
<!--        <result column="xm" property="xm"/>-->
<!--        <result column="sfzh" property="sfzh"/>-->
<!--        <result column="csrq" property="csrq" jdbcType="TIMESTAMP"/>-->
    </resultMap>

    <!-- 调用oracle存储过程返回单个结果集 -->
    <!--
        statementType="CALLABLE" :表明调用的是存储过程;
        parameterType="java.util.Map" :参数是一个map,所以在传参时需要传入一个map集合
    -->
    <select id="findDeptNameById" statementType="CALLABLE" parameterType="map">
        <!--
        1.传入传出参数要注明mode=IN/OUT
        2.并要注明jdbcType(在网上可以查询mybatis支持哪些jdbcType类型),   jdbcType=INTEGER   jdbcType=VARCHAR 等
        3.返回参数要注明对应的resultMap
        4.注意:这里deptNo,d_Name都是参数map集合的key值.  形参,和过程中的参数名无需一致
        -->
        <![CDATA[
       {call  findDeptNameById(
                    #{deptNo,mode=IN,jdbcType=VARCHAR},
                    #{d_Name,mode=OUT,jdbcType=VARCHAR}
                )}
       ]]>
    </select>

    <!-- 调用oracle存储过程返回多个结果集      参数名:deptList自定义的,用于外面Map取值:map.get("deptList"));
    -->
    <select id="findAllDeptProcedure" statementType="CALLABLE">
        <![CDATA[
            call findAllDeptProcedure(
                #{deptList, mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=deptResultMap})
        ]]>
    </select>

</mapper>

6. Oracle中的存储过程

 -- Oracle用户下创建该存储 过程,用于下方测试用
 --  测试过程1 -- 入参、出参    调用oracle存储过程返回单个结果集
    create or replace procedure findDeptNameById(v_deptno in  String, v_dname out String) is
    begin
    	-- 返回单个字符串,取出赋给出参v_dname即可
    	select xm into v_dname  from gy_brjbxxk where jzkh = v_deptno;
    end findDeptNameById;

 --   测试过程2 -- 调用oracle存储过程返回多个结果集
    create or replace procedure findAllDeptProcedure(v_dept out sys_refcursor) is
    begin
    	-- 直接将select *查询的所有数据,赋值给返回游标v_dept
    	open v_dept for select * from gy_brjbxxk where rownum <= 100;
    end findAllDeptProcedure;

7. 测试类Mybatisplus_OracleProcedure_自测通过

package com.mediinfo.healthtzplatform;

import com.alibaba.fastjson.JSONArray;
import com.mediinfo.dao.GyBrjbxxkDao;
import com.mediinfo.entity.GyBrjbxxk;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class Mybatisplus_OracleProcedure {

    @Resource
    GyBrjbxxkDao gyBrjbxxkDao;

    // 参考链接: https://blog.csdn.net/qq_45297578/article/details/121136233
    // Oracle存储过程调用  注意:  过程名区分大小写!!!
    @Test
    public void testFindDeptNameById() {
        HashMap<String, Object> map = new HashMap<>();
        // 这里的deptNo和 GyBrjbxxkDao.xml中定义的名称 一致!
        map.put("deptNo","A10014599");
        gyBrjbxxkDao.findDeptNameById(map);
        // 取得返回的内容,其实只要存储过程执行后, map里就有值了
        //		d_Name和Mapper.xml中的变量名一致
        System.out.println(map.get("d_Name"));
    }

    /**
     * 测试: 调用oracle存储过程返回多个结果集
     */
    @Test
    public void testFindAllDeptProcedure() {
		// 因该存储过程没有入参,故new个Map传入即可,方法执行后, 再通过该Map取出返回值
        Map<String, Object> param = new HashMap<String, Object>();
        gyBrjbxxkDao.findAllDeptProcedure(param);

		// 取出返回的结果集,这里变量名“deptList” 和 GyBrjbxxkDao.xml中定义的名称 一致!
        List<GyBrjbxxk> list = (List<GyBrjbxxk>) param.get("deptList");

        // 返回结果转JsonArr
        JSONArray jsonArray = (JSONArray) JSONArray.toJSON(list);
        System.out.println(jsonArray);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值