Oracle存储过程详解(四)-ibatis中调用

时间:2021-07-02 15:47:51

有一个”删除部门”的任务,删除部门的时候要先查看该部门是否还有员工,有员工就不能删除,没有就可以删除。

参考资料:

一.普通存储过程(无集合的参数)

1. 编写存储过程:

--删除一个部门(返回false0:删除失败 返回true1:删除成功 不建议使用boolean类型 jdbc不支持)
create or replace procedure delDept(dno in number,isdelete out number)
as

countEmp number;

begin
--查看此部门下是否含有员工
select count(1) into countEmp from emp where deptno = dno;

dbms_output.put_line('countEmp:' || countEmp);

if (countEmp > 0) then
/* Legacy output: */
isdelete := 0;
dbms_output.put_line('该部门下还有员工不能删除');

elsif (countEmp <= 0) then
/* Legacy output: */
delete dept where deptno = dno;
isdelete := 1;
dbms_output.put_line('部门删除成功');

else
Raise NO_DATA_FOUND;
isdelete := 0;
end if;

exception
when others then
rollback;
end delDept;

2. Ibatis中调用存储过程

sqlMap.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="AUDIT_DEPARTMENT">

<!-- ===============调用存储过程开始=============== -->
<parameterMap class="java.util.Map" id="swapParameters">
<parameter property="dno" jdbcType="INTEGER" javaType="java.lang.Integer" mode="IN" />
<parameter property="isdelete" jdbcType="INTEGER" javaType="java.lang.Integer" mode="OUT" />
</parameterMap>

<!-- 调用一个存储过程,存储过程必须指定 parameterMap,如果有返回值的话必须指定 resultMap -->
<procedure id="delDept" parameterMap="swapParameters">
<![CDATA[
{call delDept(?,?)}
]]>

</procedure>
<!-- ===============调用存储过程结束=============== -->
</sqlMap>

3. 调用

    /**
* 删除部门
*/

public void delDept(int dno) throws Exception {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("dno", dno);

getSqlMapClientTemplate().delete("AUDIT_DEPARTMENT.delDept", paramMap);
int n = (Integer) paramMap.get("isdelete");
String isDelString = n==1?"成功":"失败";
System.out.println(isDelString);
}

注:实际运行还要配置以下内容

    <!-- Spring iBatis SqlMapClient -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

4. 测试

  @Autowired
private DepartmentService departmentService;

@Test
public void testDelDept() throws Exception {
departmentService.delDept(50);
}

注:实际运行还要配置以下内容

@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试 
@ContextConfiguration({"/applicationContext.xml"}) //加载配置文件

二. Ibatis调用返回集合的存储过程

参考资料:http://blog.csdn.net/woshisap/article/details/6839719

1. 创建存储过程

create or replace procedure getEmps(p_dno in emp.empno%type,rs_cursor out SYS_REFCURSOR)
AS
BEGIN
--没有给定部门工ID则返回所有员工信息
if p_dno is null then
OPEN rs_cursor for select * from emp;

else
--返回指定部门下的员工信息
OPEN rs_cursor for select * from emp where deptno = p_dno ;
end if;

END;

2. 返回对象的实体类

public class Employee {
String name;
long employeeNumber;
long departmentNumber;
...getter setter...
}

3. sqlMap.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="AUDIT_DEPARTMENT">

<!-- ===============调用存储过程开始=============== -->
<typeAlias alias="emp" type="com.cmsz.auditvces.sell.model.Employee"/>

<resultMap class="emp" id="empMap">
<result property="name" column="ENAME" />
<result property="employeeNumber" column="EMPNO" />
<result property="departmentNumber" column="DEPTNO" />
</resultMap>

<parameterMap class="java.util.Map" id="swapParameters1">
<parameter property="p_dno" jdbcType="INTEGER" javaType="int" mode="IN" />
<parameter property="rs_cursor" jdbcType="ORACLECURSOR" javaType="cursor" mode="OUT" resultMap="empMap" />
</parameterMap>

<!-- 调用一个存储过程,存储过程必须指定 parameterMap,如果有返回值的话必须指定 resultMap -->
<procedure id="getEmps" parameterMap="swapParameters1">
<![CDATA[
{call getemps(?,?)}
]]>

</procedure>
<!-- ===============调用存储过程结束=============== -->
</sqlMap>

4. java调用

    /**
* 查询部门信息
*/

public List<Employee> getEmps(Integer dno) throws Exception {
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("p_dno", dno);
// getSqlMapClientTemplate().queryForList("AUDIT_DEPARTMENT.getEmps", paramMap);//这两个都可以用
getSqlMapClientTemplate().queryForObject("AUDIT_DEPARTMENT.getEmps", paramMap);
List<Employee> list = (List<Employee>) paramMap.get("rs_cursor");
return list;
}

5. 测试

  @Test
public void testGetEmps() throws Exception {
// Integer q = null; //返回所有员工信息
Integer q = new Integer(30);//返回当前部门员工信息
List<Employee> list = sellService.getEmps(q);
for(Employee e : list){
System.out.println(e);
}
}

三.

注意事项

  1. 存储过程的返回项不宜用Boolean类型,用起来麻烦。
  2. Oracle中的NUMBER类型 在sqlMap中配置时一定要注意,不能写成 jdbcType=”NUMBER”。没有这个类型

javaType与jdbcType类型对照

Oracle存储过程详解(四)-ibatis中调用

SQL Datatypes JDBC Typecodes Standard Java Types Java取值范围
VARCHAR2 java.sql.Types.VARCHAR java.lang.String
NUMBER java.sql.Types.NUMERIC java.math.BigDecimal 无限制
NUMBER java.sql.Types.DECIMAL java.math.BigDecimal 无限制
NUMBER java.sql.Types.BIT boolean true,false
NUMBER java.sql.Types.TINYINT byte from –128 to 127
NUMBER java.sql.Types.SMALLINT short from –32768 to 32767
NUMBER java.sql.Types.INTEGER int From –2147483648 to 2147483647
NUMBER java.sql.Types.BIGINT long From –9223372036854775808 to 9223372036854775807
NUMBER java.sql.Types.REAL float From 1.4E-45 To 3.4028235E38
NUMBER java.sql.Types.FLOAT double From 4.9E-324 to 1.7976931348623157E308
NUMBER java.sql.Types.DOUBLE double

Mybatis中调用

Oracle存储过程详解(四)-ibatis中调用
Oracle存储过程详解(四)-ibatis中调用