你的位置:首页 > 数据库

[数据库]oracle存储过程入门

http://www.360doc.com/content/14/0728/16/7662927_397682668.shtml


如何使用Mybaits调用数据库中的存储过程,下面以Oracle数据库的为例:

 1.在数据库中创建以下的存储过程:

 

java代码:
 
  1. create or replace procedure pro_hello(p_user_name in varchar2,p_result out varchar2) is  
  2. begin  
  3.   p_result := 'hello,' || p_user_name;  
  4. end;  


 

2.编写SQL映射文件mapper.

 

java代码:
 
  1. <select id="proHello" statementType="CALLABLE">  
  2. <![CDATA[  
  3.     {call pro_hello (#{p_user_name,mode=IN,jdbcType=VARCHAR},#{result,mode=OUT,jdbcType=VARCHAR})}  
  4. ]]>  
  5. </select>  


 

3.编写JAVA代码调用存储过程

 

java代码:
 
  1. public class ProcedureTest {  
  2.           
  3.          public static void main(String[] args) throws IOException {  
  4.             String resource = "mybatis.cfg.
  5.             Reader reader = Resources.getResourceAsReader(resource);  
  6.             SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);  
  7.          
  8.             SqlSession session = ssf.openSession();  
  9.          
  10.            try {  
  11.                  Map<String, String> param = new HashMap<String, String>();  
  12.                  param.put("p_user_name", "zhangsan");  
  13.                  String returnValue = (String) session.selectOne("User.proHello", param);  
  14.                  System.out.println("message=" + param.get("p_user_name"));  
  15.                  System.out.println("result=" + param.get("result"));  
  16.                  System.out.println("returnValue=" + returnValue);  
  17.    
  18.            } catch (Exception e) {  
  19.                 e.printStackTrace();  
  20.            } finally {  
  21.               session.close();  
  22.           }  
  23.        }  
  24. }  


 

4.执行Java代码,控制台输出结果如下:

 

java代码:
 
  1. 2012-03-07 20:36:32,406 DEBUG [java.sql.PreparedStatement] -==>  Executing: {call pro_hello(?,?)}  
  2. 2012-03-07 20:36:32,406 DEBUG [java.sql.PreparedStatement] -==> Parameters: zhangsan(String)  
  3. message=zhangsan  
    1. Mapper.

      Mapper.  <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 [[email protected]]
      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 [[email protected]]
      DEBUG - Closing JDBC Connection [[email protected]]
      DEBUG - Returned connection 8344960 to pool.

  4. (mybatis 调用存储过程另一种实现)Mybatis默认查询存储过程的返回值是使用参数传来传去的,从参数里获取返回值总让我感觉怪怪的,特别是在使用接口做Dao的时候,破坏了Dao接口方法的统一性。
  5. 然后就有了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
    <? 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>

     

     

    完。

普吉岛旅游去哪好普吉岛旅游团报价优惠普吉岛蜜月旅游行程参考普吉岛特价旅游多少钱到普吉岛游费用报价大全欢乐海岸《深蓝秘境》水秀表演怎么样?深圳欢乐海岸水秀演出时间? 九寨沟的洋芋糍巴好吃吗? 深圳市深蓝秘境水舞秀门票多少钱?深蓝秘境水舞秀小孩子要门票吗? 玩转津城周边 体验时下最时尚的津城周边两日游 潮州紫莲度假村网站?紫莲度假村最新活动有哪些? 2015紫莲森林度假村优惠活动?潮州紫莲森林度假村最新新闻? 2015紫莲森林度假村中秋节活动?潮州紫莲森林度假村中秋节门票多少钱? 荔枝湾游船多少钱?广州荔枝湾游船票价? 日本樱花什么时候开 四川峨眉山旅游参团游览顺序 海螺沟不可错过的美食 去韩国旅游价格多少钱_去韩国旅游要多少钱 广州晚上哪里好玩? 元宵节刚好是周日,广州哪里有花赏啊? 阳江闸坡好玩吗?有什么活动项目啊? 广州荔枝湾怎么样?好玩吗? SQCB7A3R9CAJWE Datasheet SQCB7A3R9CAJWE Datasheet 12103C474JAT2A Datasheet 12103C474JAT2A Datasheet LD031A101JAB2A Datasheet LD031A101JAB2A Datasheet 珠海到葡萄牙旅游 珠海到葡萄牙旅游 珠海到葡萄牙旅游 珠海到普吉岛旅游 珠海到普吉岛旅游 珠海到普吉岛旅游 珠海到普罗维登西亚莱斯岛旅游 珠海到普罗维登西亚莱斯岛旅游 珠海到普罗维登西亚莱斯岛旅游