SSM(MyBatis+Spring+SpringMVC)Oracle存储过程应用实战

      存储过程可以让我们的数据库操作的效率变高,因为存储过程是提前编译好了。不同于我们发送一条SQL,每次都需要经历系列步骤(语法检查——语义分析——编译——缓存——执行),使用存储过程的话直接就是执行编译好的内容,这样有利于提升系统的性能,尤其是在高并发的情况下这样的效果应该是最为明显的。那么接下来我就分享一下我是如何使用Oracle的存储过程的吧!文中的JdbcType与相应的JavaType可参照我的另一篇博客:jdbcType与Java类型对应关系表格

1. 查询数据

1.1 定义package以及存储过程
--定义package
CREATE OR REPLACE PACKAGE pk_rainQuality IS
    TYPE rainQuality_cursor IS REF CURSOR;
END pk_rainQuality;

--定义存储过程
CREATE OR REPLACE PROCEDURE getRainQulity
(
   startIndex IN NUMBER,
   maxIndex IN NUMBER,
   r_rainQulity OUT pk_rainQuality.rainQuality_cursor
) AS
BEGIN
    --分页查询语句
    OPEN r_rainQulity FOR
        SELECT * FROM (
         SELECT q1.*,ROWNUM rownum_ FROM(
            SELECT * FROM rainQuality
            ORDER BY monitorTime DESC
        ) q1 WHERE ROWNUM<=maxIndex
   ) q2 WHERE rownum_>startIndex;
END;
1.2 业务逻辑层代码实现,使用Map集合用于保存返回结果以及参数
package com.qingyun.rainQuality.service;

import com.qingyun.rainQuality.dao.RainQualityMapper;
import com.qingyun.rainQuality.pojo.RainQuality;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

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

@Service
public class RainQualityServiceImpl implements RainQualityService{

    @Resource
    RainQualityMapper rainQualityMapper;

    /**
     * 获取总记录数
     */
    @Override
    public Integer getRainQualityCount() {

        HashMap<String,Object> map=new HashMap<String,Object>();

        rainQualityMapper.getRainQualityCount(map);

        return (Integer) map.get("count");
    }

    /**
     * 获取所有雨量信息记录
     *
     * @param startIndex
     * @param maxIndex
     */
    @Override
    public List<RainQuality> getRainQualityList(Integer startIndex, Integer maxIndex) {

        HashMap<String,Object> map=new HashMap<String,Object>();

        map.put("startIndex", startIndex);
        map.put("maxIndex", maxIndex);

        rainQualityMapper.getRainQualityList(map);

        return (List<RainQuality>) map.get("rainQuality");
    }
}

1.3 DAO层Mapper接口实现
package com.qingyun.rainQuality.dao;

import org.apache.ibatis.annotations.Param;

import java.util.Map;

public interface RainQualityMapper {

    /**
     * 获取总记录数
     * @param map
     */
    public void getRainQualityCount(@Param("map")Map<String,Object> map);

    /**
     * 获取所有雨量信息记录
     * @param map
     */
    public void getRainQualityList(@Param("map")Map<String,Object> map);
}

1.4 映射文件,编写resultMap用于建立属性值与列名之间的映射关系,以及调用存储过程
<?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.qingyun.rainQuality.dao.RainQualityMapper">
    <!--定义一个列名与属性名之间的映射关系-->
    <resultMap id="rainQualityMap" type="RainQuality">
        <id property="id" column="id"/>
        <result property="districtName" column="districtName"/>
        <result property="monitorTime" column="monitorTime"/>
        <result property="rain" column="rain"/>
        <result property="monitoringStation" column="monitoringStation"/>
        <result property="monitoringAddress" column="monitoringAddress"/>
    </resultMap>

    <!--获取雨量信息总记录数-->
    <select id="getRainQualityCount" parameterType="map" statementType="CALLABLE">
        {call GETRAINQULITYCOUNT(#{map.count,mode=OUT,jdbcType=INTEGER,javaType=Integer})}
    </select>

    <!--分页查询雨量信息-->
    <select id="getRainQualityList" parameterType="map" statementType="CALLABLE">
        {call GETRAINQULITY(#{map.startIndex},#{map.maxIndex},#{map.rainQuality,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=rainQualityMap})}
    </select>
</mapper>
1.5 测试结果

测试结果

2. 新增数据

2.1 创建存储过程(使用CREATE PROCEDURE)
CREATE OR REPLACE PROCEDURE addRainQuality --定义存储过程有一点像Java中定义方法
(
    districtName IN VARCHAR2, --注意这里不允许定义大小 否则会编译出错
    monitorTime IN DATE,
    rain IN NUMBER,
    monitoringStation IN VARCHAR2,
    monitoringAddress IN VARCHAR2,
    r_result OUT NUMBER, --返回内容
    r_msg OUT VARCHAR2
) AS
BEGIN
    --保证程序的键值性 以及数据的完整性进行适当的数据验证
    IF districtName IS NULL THEN
        --抛出异常
        RAISE_APPLICATION_ERROR(-20001,'districtName IS NULL');
    ELSIF monitorTime IS NULL THEN
        RAISE_APPLICATION_ERROR(-20001,'monitorTime IS NULL');
    ELSIF rain IS NULL THEN
        RAISE_APPLICATION_ERROR(-20001,'rain IS NULL');
    ELSIF monitoringStation IS NULL THEN
        RAISE_APPLICATION_ERROR(-20001,'monitoringStation IS NULL');
    ELSIF monitoringAddress IS NULL THEN
        RAISE_APPLICATION_ERROR(-20001,'monitoringAddress IS NULL');
    ELSE
        INSERT INTO rainQuality
        VALUES(seq_rainQuality.nextval,districtName,monitorTime,
               rain,monitoringStation,monitoringAddress);
        --为返回数据赋值
        r_msg:='SUCCESS';
        r_result:=1;
    END IF;
--异常处理
EXCEPTION
    WHEN OTHERS THEN
        --为返回数据赋值
       r_msg:=SQLCODE||SQLERRM;
       r_result:=0;
END addRainQuality;
2.2 业务逻辑层代码实现
/**
     * 添加雨量信息的方法
     *
     * @param rainQuality
     */
    @Override
    public boolean addRainQuality(RainQuality rainQuality) {
        HashMap<String,Object> map=new HashMap<>();

        map.put("rain", rainQuality);

        //调用dao层进行数据持久化保存
        rainQualityMapper.addRainQuality(map);

        if (((int)map.get("result"))==1){
            return true;
        }

        logger.info(map.get("msg"));

        return false;
    }
2.3 DAO接口方法声明
 /**
     * 添加雨量信息的方法
     * @param map
     */
    public void addRainQuality(@Param("map")Map<String,Object> map);
2.4 映射文件SQL映射声明
<!--添加雨量信息-->
    <insert id="addRainQuality" parameterType="map" statementType="CALLABLE">
        {call ADDRAINQUALITY(#{map.rain.districtName},#{map.rain.monitorTime},
        #{map.rain.rain},#{map.rain.monitoringStation},#{map.rain.monitoringAddress},
        #{map.result,mode=OUT,jdbcType=INTEGER,javaType=Integer},
        #{map.msg,mode=OUT,jdbcType=VARCHAR,javaType=String})}
    </insert>
2.5 测试结果

测试结果

3. 删除数据

3.1 定义存储过程
--定义删除数据的存储过程
CREATE OR REPLACE PROCEDURE delRainQulity
(
    id NUMBER,
    r_result OUT NUMBER, --返回内容
    r_msg OUT VARCHAR2
) AS
BEGIN
    DELETE FROM rainQuality
       WHERE rainQuality.id=id;
    r_result:=1;
    r_msg:='SUCCESS';
EXCEPTION
    WHEN OTHERS THEN
       r_result:=0;
       r_msg:=SQLCODE||SQLERRM;
END;
3.2 业务逻辑层代码实现
    /**
     * 删除雨量信息的方法
     *
     * @param id
     */
    @Override
    public boolean delRainQualityById(Integer id) {
        logger.info("=================exec delRainQualityById()====================");
        logger.info("id===>"+id);

        HashMap<String,Object> map=new HashMap<>();

        map.put("id", id);

        rainQualityMapper.delRainQualityById(map);

        if (((int)map.get("result"))==1){
            return true;
        }

        logger.info(map.get("msg"));

        return false;
    }
3.3 DAO接口方法定义
    /**
     * 删除雨量信息的方法
     * @param map
     */
    public void delRainQualityById(@Param("map")Map<String,Object> map);
3.4 SQL映射信息配置
    <!--删除雨量信息-->
    <delete id="delRainQualityById" parameterType="map" statementType="CALLABLE">
        {call DELRAINQULITY(#{map.id},
        #{map.result,mode=OUT,jdbcType=INTEGER,javaType=Integer},
        #{map.msg,mode=OUT,jdbcType=VARCHAR,javaType=String})}
    </delete>
3.5 测试结果

测试结果

发布了56 篇原创文章 · 获赞 17 · 访问量 6193

猜你喜欢

转载自blog.csdn.net/qq_43199016/article/details/102757814