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