mybatis Oracle Procedure 호출하기


개인적으로 getter, setter 클래스를 만드는걸 싫어함으로 그냥 map, list 로 결과를 받는 예제를 맹글어 보겠다.

대충 요렇게 선언된 PROCEDURE_NAME 이라는 프로시져가 있다고 가정하면~
CREATE OR REPLACE PROCEDURE PROCEDURE_NAME
(
	c_resurt OUT P_OUT_CURSOR.CURSORTYPE,
	v_year  in   varchar2,
	v_term  in   varchar2,
	v_no    in   varchar2
)
AS ....

요 프로시져를 호출하는 mapper xml 파일은 요렇다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="test">
	<resultMap id="test" type="hashmap"></resultMap>
	
	<select id="test" statementType="CALLABLE">
		{ 
			CALL PROCEDURE_NAME(
				#{result, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=test},
				#{year},
				#{term},
				#{no}
			)
		}
	</select>
</mapper>

요기에서 보면 꼭 해줘야 될게

1. resultMap 을 hashmap 타입으로 하나 선언해 줘야 한다. (※ id 는 다른 xml 파일에 있는 resultMap id 와 중복되면 안된다.)

2. select 엘리먼트의 statementType 을 CALLABLE 로 설정해 줘야됨.

3. 프로시져 파라메터중 IN 타입은 잡다구리한거 설정할 필요가 없지만, OUT 타입은 위와 같이 선언해 주고 resultMap 에는 위에서 설정한 resultMap의 id를 적어줘야 한다.

요 세가지만 주의하면 mapper xml 작성은 끝~




다음으로 죠걸 호출하는 java 소스 부분이다. 편의상, 테스트 한다고 작성했던 Spring Controller 를 그대로 옮겨 적겠다. 다른데서 호출하는것도 호출방식은 다 똑같으니까 잘 땡겨다 쓸 수 있을것이라 생각한다.
package controller;

import java.util.HashMap;
import java.util.Map;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Test {
	
	@Autowired SqlSessionTemplate oracle;
	
	@RequestMapping("/test")
	public void test(ModelMap model){
		// 파라메터 셋팅
		Map param = new HashMap();
		param.put("year", "2010");
		param.put("term", "xxx");
		param.put("no", "1234");
		
		// 프로시져 호출
		oracle.selectOne("test.test", param);

		// 결과보기
		System.out.println(param);
		
		// 파라메터로 넘겨준 HashMap 에 
		// mapper xml 에서 호출할때 선언했던 #{result, mode=OUT, ~~} 
		// 요부분의 result 라는 key로 결과를 담아준다.
		// #{output, mode=OUT, ~~} 이라고 했으면 param.get("output") 으로 받으면 된다.
		model.put("result", param.get("result"));
	}
}

대충보면 알겠지만 보통 쿼리인 경우는 selectOne() 메소드의 호출결과로 쿼리결과를 리턴받지만

프로시져에서 OUT 타입 변수로 결과를 리턴할 경우 selectOne() 의 결과로 아무것도 리턴되지 않는다.

대신 호출할때 넘겨준 파라메터에 결과를 담아서 넘겨준다 -_-;



그래서 리스트로 결과를 받기 위해서 굳이 selectList 로 호출을 안해도 되고 그냥 selectOne 만 쓰면된다.

쿼리 결과가 list 인 경우 위 예제같은 경우 result 에 ArrayList 안에 HashMap 들이 들어가 있는 형태로 결과를 넣어준다.