———————————————-
사용된 개발환경
- 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에 셋팅되니 이점에 유의해서 사용해야 한다.
- IN 타입 예제[1]
- OUT 타입 예제[2]
- 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();
? ??}
??}
} |
결과
인자로 넘겨진 값인 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 이 있다.