myBatis : 프로시저 호출

———————————————-
사용된 개발환경

  • 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 NUMBER)?IS
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?val)?throws?SQLException{
? ??sqlMapper.queryForObject(“inProcedure”,?new?Integer(val));
??}

??public static?void?main(String[]?args)?throws?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 integer)?IS?
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 m)?throws?SQLException{
? ??sqlMapper.queryForObject(“outProcedure”, m);
? ??return?m;
??}

??public static?void?main(String[]?args)?throws?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 integer)?IS
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 m)?throws?SQLException{
? ??sqlMapper.queryForObject(“inoutProcedure”, m); ? ?
? ??return?m;
??}

??public static?void?main(String[]?args)?throws?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이다. 즉 프로시저의 처리고 값이 정상적으로 바껴서 넘어온것이다.

 

 

================================================================

@SuppressWarnings(“unchecked”)
public String callProc(HashMap map) throws SQLException {
sqlMapClient.queryForObject(“testProc”, map);
String error = CommonUtil.toString(map.get(“resultMsg”));
return error;
}

* 결과셋 반환 : queryForList(), queryForObject()
* 결과 한개 이상 반환 : queryForList()
* 결과 한개 : queryForObject()
* 결과 반환 않거나, 파라미터에 결과셋을 셋팅하지 않을때 : update()

=========================================================================

 

{ CALL PROC_TEST(?,?) }

================================================================

* mode 속성값으로는 IN, OUT, INOUT 이 있다.

Leave a Reply

Your email address will not be published.