관리 메뉴

nalaolla

IBatis의 Procedure 사용예제 본문

IBatis

IBatis의 Procedure 사용예제

날아올라↗↗ 2015. 12. 1. 00:45
728x90
----------------------------------------------
사용된 개발환경
  • iBATIS : 2.3.0.677
  • Oracle : 10g
  • eclipse : wtp All-in-one R-1.5.4-200705021353

 

  • xml설정파일에서는 대소문자 구분이 의외로 굉장히 중요하다. 필자의 경우 jdbcType 의 값을 INTEGER로 줘야 하는데도 불구하고 Integer로 줘서 한참동안이나 고생을 했다.
  • Procedure에서는 Map을 사용할 경우 queryForObject 메소드의 반환 객체에 값이 셋팅되는것이 아니고 넘긴 객체에 값이 셋팅된다. 기본적으로 반환되는 Map객체는 null로 넘어온다. 프로시저에서 넘긴값을 인자로 넘긴 Map에 셋팅되니 이점에 유의해서 사용해야 한다.
  1. IN 타입 예제[1]
  2. OUT 타입 예제[2]
  3. INOUT 타입 예제[3]

IN타입[#1]

  • IN파라미터란! : 호출자에 의해 프로시저에 전달되는 파라미터이고 읽기전용의 값이다. 즉 프로시저는 이 값을 변경할수는 없다.
  • 테스트 케이스 : 여기서는 IN타입으로 값을 받아와서 특정 테이블에 값을 입력하는 케이스를 보여준다.

프로시저

 

CREATE OR REPLACE PROCEDURE procedurein (p_param IN NUMBERIS
BEGIN
   DBMS_OUTPUT.put_line (p_param);
   INSERT INTO tablein VALUES (p_param);
   commit;
END;
/

테이블 생성

create table tablein(val number);

sqlMap파일

 

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <procedure id="inProcedure" parameterClass="java.lang.Integer">
    call procedurein(#val#) }
  </procedure>
</sqlMap>

실행코드

 

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static void callInTypeProcedure(int valthrows SQLException{
    sqlMapper.queryForObject("inProcedure"new Integer(val));
  }

  public static void main(String[] argsthrows SQLException {
    
    try {
      callInTypeProcedure(123);
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과

 

SQL> select * from tableIN;

       VAL
----------
       123

SQL>

여기서 보면 인자로 123이라는 숫자값을 넘겼으며 프로시저에 정의된 내용대로 tableIN이라는 테이블에 값이 정상적으로 입력이 된것을 볼수 있다.

OUT타입[#2]

  • OUT파라미터란! : 프로시저에서 값이 변경될수 있다. 이 파라미터는 프로시저가 다수의 정보를 호출자에게 반환시켜주어야 하는 경우에 주로 사용한다.
  • 테스트 케이스 : 여기서는 IN타입으로 입력된 숫자값에 3을 더한 값을 반환하는 것을 보여주는 예제이다.

프로시저

 

CREATE OR REPLACE PROCEDURE procedure_out(p_inval in integer, p_outval out integerIS 
BEGIN
   p_outval := p_inval+3;
END;
/

sqlMap파일

 

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <parameterMap id="outProcedureMap" class="java.util.Map">
    <parameter property="p_inval" javaType="java.lang.Integer" jdbcType="INTEGER" mode="IN" />
    <parameter property="p_outval" javaType="java.lang.Integer" jdbcType="INTEGER" mode="OUT" />
  </parameterMap>
  
  <procedure id="outProcedure" parameterMap="outProcedureMap">
    call procedure_out (?,?) }
  </procedure>
</sqlMap>

실행코드

 

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static Map callOutTypeProcedure(Map mthrows SQLException{
    sqlMapper.queryForObject("outProcedure", m);
    return m;
  }

  public static void main(String[] argsthrows SQLException {    
    try {
      Map<String, Integer> m = new HashMap<String, Integer>(2);
      m.put("p_inval"new Integer(123));      
      Map result = SimpleExample.callOutTypeProcedure(m);
      System.out.println("result : " + Integer.parseInt(result.get("p_outval").toString()));    
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과

 

result : 126

인자로 넘겨진 값인 123에 3을 더해 126이라는 값이 반환되었다.

INOUT타입[#3]

  • INOUT파라미터란! : 프로시저가 읽고 쓰는 작업을 동시에 할수 있는 파라미터를 의미한다.
  • 테스트 케이스 : 여기서는 INOUT타입으로 값을 받아와서 값의 위치를 서로 바꿔서 값을 입력한 뒤 반환하는 케이스를 보여주는 예제이다.

프로시저

 

CREATE OR REPLACE PROCEDURE procedure_inout(p_inout1 in out integer, p_inout2 in out integerIS
tmpVar NUMBER;
BEGIN
   tmpVar:=p_inout1;
   p_inout1:=p_inout2;
   p_inout2:=tmpVar;
END;
/

sqlMap파일

 

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <parameterMap id="inoutProcedureMap" class="java.util.Map">
    <parameter property="p_inout1" javaType="java.lang.Integer" jdbcType="INTEGER" mode="INOUT" />
    <parameter property="p_inout2" javaType="java.lang.Integer" jdbcType="INTEGER" mode="INOUT" />
  </parameterMap>  
  
  <procedure id="inoutProcedure" resultClass="java.util.Map" parameterMap="inoutProcedureMap">
    call procedure_inout(?, ?) }
  </procedure>  
</sqlMap>

실행코드

 

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static Map callProcedure(Map mthrows SQLException{
    sqlMapper.queryForObject("inoutProcedure", m);    
    return m;
  }

  public static void main(String[] argsthrows SQLException {
    
    try {
      Map<String, Integer> m = new HashMap<String, Integer>(2);
      m.put("p_inout1"new Integer(7));
      m.put("p_inout2"new Integer(5));
      System.out.println("인자로 넘어가는 값 \n"+m);
      Map map = (HashMap)SimpleExample.callProcedure(m);
      System.out.println("결과로 넘어온 값 \n"+m);
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과

 

인자로 넘어가는 값 
{p_inout1=7, p_inout2=5}
결과로 넘어온 값 
{p_inout1=5, p_inout2=7}

보면 처음에 넘긴값은 p_inout1값이 7이고 p_inout2값인데 반환값은 반대로 5, 7이다. 즉 프로시저의 처리고 값이 정상적으로 바껴서 넘어온것이다.

728x90