http://www.360doc.com/content/14/0728/16/7662927_397682668.shtml
如何使用Mybaits调用数据库中的存储过程,下面以Oracle数据库的为例:
1.在数据库中创建以下的存储过程:
2.编写SQL映射文件mapper.xml:
3.编写JAVA代码调用存储过程
4.执行Java代码,控制台输出结果如下:
Mapper.xml 配置
<resultMap type="emp" id="empMap">
<id property="empno" column="empno"/>
<result property="ename" column="ename"/>
<result property="mgr" column="mgr"/>
<result property="job" column="job"/>
<result property="hiredate" column="hiredate"/>
<result property="sal" column="sal"/>
<result property="comm" column="comm"/>
</resultMap>
<!-- 调用存储过程返回结果集 -->
<select id="getEmps" parameterType="java.util.Map" statementType="CALLABLE">
<![CDATA[
call pro_emp(#{emps,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=empMap}) ]]>
</select>
存储过程:
create or replace procedure pro_emp(cur_sys out sys_refcursor)
as
begin
open cur_sys for select empno, ename, job, mgr, hiredate, sal, comm, deptno
from tb_emp;
end;
IOperation接口里的方法 :
public interface IOperation {
void getEmps(Map<String, Object> param);
}
测试类:
public class Mytest {
private SqlSession sqlSession;
private IOperation mapper;
@Before
public void before(){
try {
SqlSessionFactory factory=MyBatisUtil.getSqlSessionFactory();
sqlSession=factory.openSession();
mapper=sqlSession.getMapper(IOperation.class);
System.out.println("start");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
@Test
public void getEmps(){
try {
Map<String, Object> param = new HashMap<String, Object>();
param.put("emps",OracleTypes.CURSOR);
mapper.getEmps(param);
List<Emp> depts =(List<Emp>)param.get("emps");
for (Emp emp : depts) {
System.out.println(emp.getEmpno()+" "+emp.getEname());
}
} catch (Exception e) {
System.out.println("getEmp: "+e.getMessage());
}
}
@After
public void after(){
System.out.println("close");
sqlSession.close();
}
}
结果:
start
DEBUG - Openning JDBC Connection
DEBUG - Created connection 8344960.
DEBUG - ooo Using Connection [oracle.jdbc.driver.T4CConnection@7f5580]
DEBUG - ==> Preparing: call pro_emp(?)
DEBUG - ==> Parameters:
123 liuzan
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
close
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@7f5580]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@7f5580]
DEBUG - Returned connection 8344960 to pool.
然后就有了mybatis-callable,获得方式如下:
1
2
3
4
5
6
7
8
9
|
<
dependencies
>
...
<
dependency
>
<
groupId
>com.github.miemiedev</
groupId
>
<
artifactId
>mybatis-callable</
artifactId
>
<
version
>1.0</
version
>
</
dependency
>
...
</
dependencies
>
|
配置是这样的:
1
2
3
4
5
6
7
8
9
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!
DOCTYPE
configuration
PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<
configuration
>
<
plugins
>
<
plugin
interceptor
=
"com.github.miemiedev.mybatis.callable.CallableConvertInterceptor"
> </
plugin
>
</
plugins
>
</
configuration
>
|
创建一个查询,需要注意的是只有statementType为CALLABLE时拦截器才会起作用:
1
2
3
4
5
6
7
8
9
|
<
select
id
=
"query2"
statementType
=
"CALLABLE"
>
<![CDATA[
{call test_proc2(
#{acResult,mode=OUT,jdbcType=CURSOR,javaType=ResultSet, resultMap=hashMap},
#{userType},
#{branchCode}
)}
]]>
</
select
>
|
然后Dao或许是这样的,接口也是一样的:
1
2
3
4
5
6
7
|
public List<
Map
<String, Object>> query2(String userType, String branchCode){
Map<
String
, Object> params = new HashMap<
String
, Object>();
params.put("userType",userType);
params.put("branchCode",branchCode);
//存储过程只返回一个游标,则使用selectList返回List
return getSqlSession().selectList("db.table.user.query2", params);
}
|
===========================================
返回单个参数但是不是游标的话就这样
1
2
3
4
5
6
7
8
9
|
<
select
id
=
"query3"
statementType
=
"CALLABLE"
>
<![CDATA[
{call test_proc3(
#{retCode,mode=OUT,jdbcType=INTEGER},
#{userType},
#{branchCode}
)}
]]>
</
select
>
|
1
2
3
4
5
6
7
|
public Integer query3(String userType, String branchCode){
Map<
String
, Object> params = new HashMap<
String
, Object>();
params.put("userType",userType);
params.put("branchCode",branchCode);
//存储过程只有一个返回值,并且不是游标,则使用selectOne
return getSqlSession().selectOne("db.table.user.query3", params);
}
|
===========================================
返回多个参数,里面啥都有:
1
2
3
4
5
6
7
8
9
10
|
<
select
id
=
"query"
statementType
=
"CALLABLE"
>
<![CDATA[
{call test_proc(
#{retCode,mode=OUT,jdbcType=INTEGER},
#{acResult,mode=OUT,jdbcType=CURSOR,javaType=ResultSet, resultMap=hashMap},
#{userType},
#{branchCode}
)}
]]>
</
select
>
|
1
2
3
4
5
6
7
|
public Map<
String
, Object> query(String userType, String branchCode){
Map<
String
, Object> params = new HashMap<
String
, Object>();
params.put("userType",userType);
params.put("branchCode",branchCode);
//存储过程只有一个返回值,并且不是游标,则使用selectOne
return getSqlSession().selectOne("db.table.user.query", params);
}
|
Map中包含所有存储过程输出的结果,Key是存储过程的参数名,按需来取就行了。
=============================================
上面看上去规则有点麻烦,其实用接口做的话就不用考虑是selectList还是selectOne了,直接接收返回值就可以。
=============================================
自己定义结果集的话参考一下SimpleResultHandler的实现就行了,反正把自己实现的按照下面这么配就行了。不配resultHandler的话默认就是SimpleResultHandler了。
1
2
3
|
<
plugin
interceptor
=
"com.github.miemiedev.mybatis.callable.CallableConvertInterceptor"
>
<
property
name
=
"resultHandler"
value
=
"com.github.miemiedev.mybatis.callable.handler.SimpleResultHandler"
/>
</
plugin
>
|
完。