有一个”删除部门”的任务,删除部门的时候要先查看该部门是否还有员工,有员工就不能删除,没有就可以删除。
一.普通存储过程(无集合的参数)
1. 编写存储过程:
--删除一个部门(返回false或0:删除失败 返回true或1:删除成功 不建议使用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);
}
}
三.
注意事项
- 存储过程的返回项不宜用Boolean类型,用起来麻烦。
- Oracle中的NUMBER类型 在sqlMap中配置时一定要注意,不能写成 jdbcType=”NUMBER”。没有这个类型
javaType与jdbcType类型对照
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 |