MyBatis(14)——MyBatis调用Oracle存储过程

目录

创建存储过程:

在Oracle中调用:

MyBatis中调用

创建参数对象

Mapper接口方法

Mapper的SQL调用

测试调用


创建存储过程:

Oracle中创建一个有输入参数输出参数、并且输出参数为系统游标的存储过程。

-- 传入开始的页面、结束页面,输出游标为分页查询的employee数据
create or replace procedure getEmpByPage(v_beginPage in int,v_endPage in int,c_emp out sys_refcursor)
as
begin
  open c_emp for
  select
      *
  from (
         select rownum as rid,emp.* from employees emp
  )where rid between (v_beginPage) and (v_endPage);

end;

在Oracle中调用:

首先声明的变量v_emp为employees表的行类型。

但是 存储过程中查询的数据额外增加了一个rownum行号,所以调用的时候会出现“类型不匹配”的错误。

可以将存储过程中查询的*替换为具体的字段,匹配employee表的字段类型。

declare
v_emp employees%rowtype;
c_emp sys_refcursor;
begin 
  getempbypage(1,5,c_emp);
  loop
    fetch c_emp into v_emp;
    exit when c_emp%notfound;
    dbms_output.put_line(v_emp.employee_id||','||v_emp.first_name||','||v_emp.email);
  end loop;
  close c_emp;
end;

MyBatis中调用

创建参数对象

包含存储过程中的输入、输出参数及其游标的返回类型:

public class OraclePage {

    private Integer beginPage;
    private Integer endPage;
    private List<Employee> emps;

    //getter、setter

}

Mapper接口方法

public void getEmpByProcedure(OraclePage page);

Mapper的SQL调用

<select id="getEmpByProcedure" statementType="CALLABLE" useCache="false">
	{
		call getempbypage(
			#{beginPage,mode=IN,jdbcType=INTEGER},
			#{endPage,mode=IN,jdbcType=INTEGER},
			#{emps,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=PageEmp}
		)
	}	
</select>

<resultMap type="com.starfall.mybaits.entity.Employee" id="PageEmp">
	<id column="employee_id" property="employeeId"/>
	<result column="first_name" property="firstName"/>
	<result column="last_name" property="lastName"/>
</resultMap>

1、select标签中的statementType属性指定为"CALLABLE" ,useCache使用缓存最好设置为false。(测试发现存储过程不支持二级缓存)

2、存储过程的参数需要指定mode属性,值为IN、OUT、INOUT。同时需要指定jdbcType的枚举类型,Oracle的游标为CURSOR

3、对于返回参数的游标类型。需要指定javaType=ResultSet,并且指定resultMap=PageEmp接收返回的数据。

测试调用

@Test
public void testProcedure() throws IOException {
	String resource = "mybatis-config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	SqlSession session = sqlSessionFactory.openSession();
	try {
		EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
		OraclePage page = new OraclePage();
		page.setBeginPage(1);
		page.setEndPage(5);
		mapper.getEmpByProcedure(page);
		List<Employee> list = page.getEmps();
		for (Employee employee : list) {
			System.out.println(employee);
		}
	} finally {
		session.close();
	}
}

传入创建的OraclePage对象,存储过程查出的数据会根据属性set到对象中。


测试发现,Mybatis调用存储过程需要将输入输出参数包装成一个整体的对象,在传入查询的接口中,如果接口为下方类似的写法:

public void getEmpByProcedure(@Param("beginPage") int beginPage, @Param("endPage") int endPage,
        @Param("emps") List<Employee> emps);

反而获取不到查出的数据:List<Employee> emps总是为空。

具体原因有待进一步探究。。。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值