存储过程可以让我们的数据库操作的效率变高,因为存储过程是提前编译好了。不同于我们发送一条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>