mybatis3调用oracle存储过程

来源:互联网 发布:预科生的贩毒网络 srt 编辑:程序博客网 时间:2024/06/06 05:52

oracle的存储过程,如果要查询数据必须有一个游标供使用 

先看下简单的存储过程 

 

Sql代码  收藏代码
  1. CREATE OR REPLACE PROCEDURE zdrqlx_PROC  
  2.     (  
  3.            V_TEMP OUT zdrqlxPackage.zdrqlx_cursor  
  4.    )  
  5.    AS  
  6.    BEGIN  
  7.            OPEN V_TEMP FOR SELECT LXMC FROM TBGW_ZHDRQFL ;  
  8. END zdrqlx_PROC;  

 

 

这个存储过程查询后 结果是 一列数据 列名 LXMC 

 

下面贴查询mybatis的配置

 

 

Xml代码  收藏代码
  1. <resultMap id="teshurenqunMap" type="bean.admin.menus.ZhongDianRenQunBean" >  
  2. <result column="lxmc" property="lxmc" />  
  3. </resultMap>  
  4.   
  5. <select id="selectByMap"  parameterType="map"   statementType="CALLABLE" >  
  6.     { call zdrqlx_PROC(#{listinfo,mode=OUT,jdbcType=CURSOR,javajavaType=java.sql.ResultSet,resultMap=teshurenqunMap})}  
  7. </select>  

 

 

程序调用的是selectByMap 这个方法 在调用的时候 需要传入一个参数 这里参数名是map ,map内可以什么属性都没有, 在mybatis调用存储过程后,会把数据 回塞给这个map

所以 如果你的程序是   Map resultmap = dao.selectByMap(map); 

然后去读取resultmap ,结果会是null的 什么都没有,而数据实际上在被存在参数的map里面 而不是resultmap  (map 是参数map,resultmap 是返回接收的) 这点很重要,我被卡住了半天!!!

 

下面是调用  看了上面一段话 下面的程序一目了然

 

 

 

Java代码  收藏代码
  1. Map map = new HashMap();  
  2.          menusService.getToolsBarMunus(map);//这里调用selectByMap  
  3.          map.put("success"true);  
  4. /这边数据会存在这个参数map里,是被回填的了  
  5.         datas.append(com.alibaba.fastjson.JSON.toJSONString(map));  

 

 

com.alibaba.fastjson.JSON.toJSONString(map)  

这句话是用的json组件转化map得到string,结果是下面的

 

{"listinfo":[{"lxmc":"张三"},{"lxmc":"李四"},{"lxmc":"王五"}{"lxmc":"赵六"}]}

根据结果,反过来看调用存储过程

{ call zdrqlx_PROC(#{listinfo,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=teshurenqunMap})}

 

1. listinfo 这个是第一个参数,我是随意写的,不和任何东西管理,看下上面json转化后的map结果就明白了

2  mode=OUT 声明此参数作为输出类型

3  jdbcType=CURSOR 说明他是游标 因为这个存储过程主要是查询,需要传入一个游标参数,不信的话你在plsql里面test存储过程 看下面就明白了

javaType=java.sql.ResultSet, 貌似固定要求这样,求大神解答

 5 resultMap 必须有这个参数 我这里配置的 是resultMap id="teshurenqunMap" 对应的

 

 

最后是我的bean 也就是resultMap 设置的type=

 

Java代码  收藏代码
  1. package bean.admin.menus;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class ZhongDianRenQunBean {  
  6.     private String lxmc;  
  7.     public String getLxmc() {  
  8.         return lxmc;  
  9.     }  
  10.   
  11.     public void setLxmc(String lxmc) {  
  12.         this.lxmc = lxmc;  
  13.     }  
  14.   
  15. }  

 -------------------------------------------------------------------------------------------------------------------------------------------------------------------

mybatis调用存储过程

参数形式: 
Sql代码  收藏代码
  1. create procedure sptest.adder(in addend1 integerin addend2 integerout theSum integer)  
  2. begin atomic  
  3.   set theSum = addend1 + addend2;   
  4. end  
  5. go  


Xml代码  收藏代码
  1. <parameterMap type="map" id="testParameterMap">  
  2.    <parameter property="addend1" jdbcType="INTEGER" mode="IN"/>  
  3.    <parameter property="addend2" jdbcType="INTEGER" mode="IN"/>  
  4.    <parameter property="sum" jdbcType="INTEGER" mode="OUT"/>  
  5.  </parameterMap>  
  6. lt;update id="adderWithParameterMap" parameterMap="testParameterMap" statementType="CALLABLE">  
  7.    {call sptest.adder(?, ?, ?)}  
  8.  </update>  

Java代码  收藏代码
  1. public void testAdderAsUpdateWithParameterMap() {  
  2.        SqlSession sqlSession = sqlSessionFactory.openSession();  
  3.        try {  
  4.            Map<String, Object> parms = new HashMap<String, Object>();  
  5.            parms.put("addend1"3);  
  6.            parms.put("addend2"4);  
  7.              
  8.            SPMapper spMapper = sqlSession.getMapper(SPMapper.class);  
  9.              
  10.            spMapper.adderWithParameterMap(parms);  
  11.            assertEquals(7, parms.get("sum"));  
  12.              
  13.            parms = new HashMap<String, Object>();  
  14.            parms.put("addend1"2);  
  15.            parms.put("addend2"3);  
  16.            spMapper.adderWithParameterMap(parms);  
  17.            assertEquals(5, parms.get("sum"));  
  18.              
  19.        } finally {  
  20.            sqlSession.close();  
  21.        }  


带输入输出参数的存储过程: 
sql代码:
Sql代码  收藏代码
  1. create procedure sptest.getnames(in lowestId intout totalrows integer)  
  2. reads sql data  
  3. dynamic result sets 1  
  4. BEGIN ATOMIC  
  5.   declare cur cursor for select * from sptest.names where id >= lowestId;  
  6.   select count(*) into totalrows from sptest.names where id >= lowestId;  
  7.   open cur;  
  8. END  
  9. go  



Xml代码  收藏代码
  1. <select id="getNamesAndItems" statementType="CALLABLE"  
  2.     <select id="getNames" parameterType="java.util.Map" statementType="CALLABLE"  
  3.   resultMap="nameResult">  
  4.   {call sptest.getnames(  
  5.     #{lowestId,jdbcType=INTEGER,mode=IN},  
  6.     #{totalRows,jdbcType=INTEGER,mode=OUT})}  
  7. </select>  
  8. </select>  


Java代码  收藏代码
  1. public void testCallWithResultSet2_a1() {  
  2.        SqlSession sqlSession = sqlSessionFactory.openSession();  
  3.        try {  
  4.            SPMapper spMapper = sqlSession.getMapper(SPMapper.class);  
  5.              
  6.            Map<String, Object> parms = new HashMap<String, Object>();  
  7.            parms.put("lowestId"1);  
  8.            List<Name> names = spMapper.getNamesAnnotated(parms);  
  9.            assertEquals(3, names.size());  
  10.            assertEquals(3, parms.get("totalRows"));  
  11.        } finally {  
  12.            sqlSession.close();  
  13.        }  
  14.    }  



返回多个结果集 
sql代码:
Sql代码  收藏代码
  1. create procedure sptest.getnamesanditems()  
  2. reads sql data  
  3. dynamic result sets 2  
  4. BEGIN ATOMIC  
  5.   declare cur1 cursor for select * from sptest.names;  
  6.   declare cur2 cursor for select * from sptest.items;  
  7.   open cur1;  
  8.   open cur2;  
  9. END  
  10. go  



Xml代码  收藏代码
  1. <resultMap type="org.apache.ibatis.submitted.sptests.Name" id="nameResult">  
  2.     <result column="ID" property="id"/>  
  3.     <result column="FIRST_NAME" property="firstName"/>  
  4.     <result column="LAST_NAME" property="lastName"/>  
  5.   </resultMap>  
  6.   
  7.   <resultMap type="org.apache.ibatis.submitted.sptests.Item" id="itemResult">  
  8.     <result column="ID" property="id"/>  
  9.     <result column="ITEM" property="item"/>  
  10.   </resultMap>  
  11.   
  12.   <select id="getNamesAndItems" statementType="CALLABLE"  
  13.     resultMap="nameResult,itemResult">  
  14.     {call sptest.getnamesanditems()}  
  15.   </select>  


Java代码  收藏代码
  1. @Test  
  2.     public void testGetNamesAndItems() throws SQLException {  
  3.         SqlSession sqlSession = sqlSessionFactory.openSession();  
  4.         try {  
  5.             SPMapper spMapper = sqlSession.getMapper(SPMapper.class);  
  6.               
  7.             List<List<?>> results = spMapper.getNamesAndItems();  
  8.             assertEquals(2, results.size());  
  9.             assertEquals(4, results.get(0).size());  
  10.             assertEquals(3, results.get(1).size());  
  11.         } finally {  
  12.             sqlSession.close();  
  13.         }  
  14.     }  

注意: 

上面就是几种常用的了。 
1 sqlserver oracle sqlserver返回结果集是可以不要out参数的。如果sql中用的是select出结果,不需要配置out参数。多个结果集/结果集可以配置resultMap 来返回LIST,主要是调用selectList方法会自动把结果集加入到list中去的。 
2 sql有返回值 用select标签 
3 注意sql参数和mybatis参数的对应关系,这个这里就不讲了。 
4 注意参数个数 

我遇到的异常: 

参数不匹配的原因,因为sqlserver 中我是直接返回select临时表结果,不需要配置存储过程输出参数。 
list中的内容形式: 
 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


存储过程都是一样的,只是根据自己的喜好,可以用MAP或者JAVABEAN传递参数。

Sql代码  收藏代码
  1. -- --------------------------------------------------------------------------------  
  2. -- Routine DDL  
  3. -- Note: comments before and after the routine body will not be stored by the server  
  4. -- --------------------------------------------------------------------------------  
  5. DELIMITER $$  
  6.   
  7. CREATE DEFINER=`root`@`localhost` PROCEDURE `selectCount`(  
  8.     IN pcsId int,  
  9.     IN drId int,  
  10.     IN partnerId int,  
  11.     IN customerId int,  
  12.     OUT pcsCount int,  
  13.     OUT drCount int  
  14.       
  15. )  
  16. BEGIN  
  17.       
  18.     select count(md.id) into @pcsC from mdm_device md   
  19. left join mdm_device_security mds on mds.device_id = md.id  
  20. where mds.device_rooted = pcsId  
  21. and md.partner_id = partnerId and md.customer_id = customerId;  
  22. set pcsCount = @pcsC;  
  23.   
  24.   
  25. select count(md.id) into @drC from mdm_device md  
  26. where md.managed_status = drId and  DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(md.un_manage_date)  
  27. and md.partner_id = partnerId and md.customer_id = customerId;  
  28. set drCount = @drC;  
  29.   
  30.   
  31.   
  32. END  

 

 

1.java调用传入MAP。获取通过MAP获取。

1.1 mapper文件写法

Xml代码  收藏代码
  1. <parameterMap type="map" id="homeVO">    
  2.    <parameter property="pcsId" jdbcType="INTEGER" mode="IN"/>    
  3.    <parameter property="drId" jdbcType="INTEGER" mode="IN"/>    
  4.    <parameter property="partnerId" jdbcType="INTEGER" mode="IN"/>    
  5.    <parameter property="customerId" jdbcType="INTEGER" mode="IN"/>    
  6.    <parameter property="pcsCount" jdbcType="INTEGER" mode="OUT"/>    
  7.    <parameter property="drCount" jdbcType="INTEGER" mode="OUT"/>    
  8.  </parameterMap>    
  9. <select id="selectForHome" parameterMap="homeVO"   
  10.       statementType="CALLABLE">  
  11.       {call selectCount(  
  12.         ?,?,?,?,?,?  
  13.       )}  
  14.   </select>  

 1.2 java调用写法

Java代码  收藏代码
  1. @Override  
  2.     public StringselectHomeCount(HomeVO home) throws Exception {  
  3.         Map<String, Object> map = new HashMap<String, Object>();  
  4.         map.put("pscId"0);    
  5.         map.put("drId"1);  
  6.         map.put("partnerId"25);  
  7.         map.put("customerId"50);  
  8.         map.put("isolation"1);  
  9.         selectOne("Mapper.selectForHome", map);  
  10.         System.out.println(map.get("pcsCount"));  
  11.           
  12.             return map.get("drCount");  
  13.     }  

 

 

2.java调用传入javaBean。返回值通过javaBean属性获取

2.1 通过javabean传递参数  mapper写法

Xml代码  收藏代码
  1. <parameterMap type="com.polysaas.mdm.device.entity.HomeVO" id="home">  
  2.      <parameter property="pcsId" jdbcType="INTEGER" mode="IN"/>    
  3.    <parameter property="drId" jdbcType="INTEGER" mode="IN"/>    
  4.    <parameter property="partnerId" jdbcType="INTEGER" mode="IN"/>    
  5.    <parameter property="customerId" jdbcType="INTEGER" mode="IN"/>    
  6.    <parameter property="pcsCount" jdbcType="INTEGER" mode="OUT"/>    
  7.    <parameter property="drCount" jdbcType="INTEGER" mode="OUT"/>  
  8.  </parameterMap>  

 javaBean可以通过两种来进行映射

Xml代码  收藏代码
  1. <resultMap type="com.polysaas.mdm.device.entity.HomeVO" id="home">  
  2.         <result column="partnerId" property="partnerId" jdbcType="INTEGER"/>  
  3.         <result column="customerId" property="customerId" jdbcType="INTEGER" />  
  4.         <result column="pcsId" property="pcsId" jdbcType="INTEGER" />  
  5.         <result column="drId" property="drId" jdbcType="INTEGER" />  
  6.         <result column="pcsCount" property="pcsCount" jdbcType="INTEGER" />  
  7.         <result column="drCount" property="drCount" jdbcType="INTEGER" />  
  8.   </resultMap>  
  9.   <select id="selectForHome2" parameterType="com.polysaas.mdm.device.entity.HomeVO"   
  10.       statementType="CALLABLE">  
  11.       {call selectCount(  
  12.         #{pcsId,jdbcType=INTEGERmode=IN},  
  13.         #{drId, jdbcType=INTEGER,mode=IN},  
  14.         #{partnerId, jdbcType=INTEGER,mode=IN},  
  15.         #{customerId, jdbcType=INTEGER,mode=IN},  
  16.         #{pcsCount, jdbcType=INTEGER,mode=OUT},  
  17.         #{drCount, jdbcType=INTEGER,mode=OUT}  
  18.       )}  
  19.   </select>  

 2.2 通过javabean传递参数  java调用写法

Java代码  收藏代码
  1. @Override  
  2. public HomeVO selectHomeCount(HomeVO home) throws Exception {  
  3. HomeVO vo = new HomeVO();  
  4. vo.setPcsId(0);  
  5. vo.setDrId(0);  
  6. vo.setPartnerId(25);  
  7. vo.setCustomerId(50);  
  8. vo.setPcsCount(0);  
  9. vo.setDrCount(0);  
  10. selectOne("com.polysaas.mdm.device.mapper.MdmDeviceMapper.selectForHome2", vo);  
  11. return vo;  
  12. }  

 

 

遇到异常很多。。记得的写下

1.通过javaBean的时候,#{pcsId, mode=IN, javaType=INTEGER},javaType这个属性是必须的。

2.使用javaBean传递。输出参数不需要初始值。个人喜好并建议使用javaBean,因为定义更清晰,封装性。

3.map可以用占位符问号,javaBean不可以。  会有异常 No value specified for parameter 1

4.   说不认识某个参数。。可能是没有创建存储过程,这个发生在多个库的时候

5.  read Only  这个可能是事务控制只读。。我是因为存储过程有set 语句,而方法叫做selectAaaa()。




 

0 0