zoukankan      html  css  js  c++  java
  • 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.xml:

    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.xml";  
    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.xml 配置

        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.

    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
      <?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>

      完。

  • 相关阅读:
    小程序的目录结构及基本代码编写流程
    vue+hbuilder监听安卓返回键问题
    VUE项目用hbuilder 打包为手机APP
    VUE组件相关总结!
    VUE常用指令总结!
    vue开发者工具vue-devtools-4.1.4_0.crx谷歌插件下载及安装
    vue-cli环境搭建初探!
    PHP返回Json数据函数封装
    WeX5入门之HelloWorld
    WeX5入门之欢乐捕鱼打包
  • 原文地址:https://www.cnblogs.com/leo3689/p/4576990.html
Copyright © 2011-2022 走看看