Creative Wrong Answer


2010/11/02 - [Java & iBatis] - Java / iBatis에서 프로시저 호출하기
2010/11/05 - [Java & iBatis] - iBatis에서 myBatis로 개요 및 변경점

이 포스트를 읽기전에 이전글을 안읽었다면 한번 둘러보고 오는편이 좋을 것같아서 링크를 먼저 걸고 시작한다.
iBatis 에서 프로시저 호출하기의 myBatis 버전이다.

myBatis 에서 paramterMap을 더이상 사용하지 말자고 했기 때문에.. 이전처럼 프로시저를 호출하는 것은 무리가 있다.

Procedure 관련 체크해야할 변경사항은.. 일단 parameterMap이 사라진것.. 그리고 <procedure > 가 사라지고 type 으로 판단하게 된것이다.

parameterMap이 사라지고 MyBatis에서는 inlineStatement를 사용하라고 이야기 하고있다.  이것은 #{var}안에 직접 파라미터를 넣어서 사용하는 방법이다. 이방법에 따라서 이전 소스를 myBatis 버전으로 컨버팅 해보자.



iBatis 소스

<parametermap id="blParam" class="map">
<parameter property="p_latitude" jdbctype="VARCHAR" javatype="java.lang.String" mode="IN">
<parameter property="p_longitude" jdbctype="VARCHAR" javatype="java.lang.String" mode="IN">
<parameter property="p_utmx" jdbctype="DECIMAL" javatype="long" mode="OUT">
<parameter property="p_utmy" jdbctype="DECIMAL" javatype="long" mode="OUT">
</parameter></parameter></parameter></parameter></parametermap>
<procedure id="bl_to_utm" parametermap="blParam">
{call PROC_BL_TO_UTM(?,?,?,?)}
</procedure>



<procedure > 태그를 사용해서 프로시저를 정의 하고 들어오는 변수는 parameterMap에 정의해놓았다.

java 소스
Map map = new HashMap();
map.put("p_latitude",vo.getX_latitude());
map.put("p_longitude", vo.getX_longitude());
sqlMapper.update("VocIphone.bl_to_utm", map );
					
System.out.println(map.get("p_utmx").toString());
System.out.println(map.get("p_utmy").toString());


자바쪽에서는 map에 IN 타입 변수를 담아서 쿼리를 실행시키고 map의 OUT 타입 변수에 엑세스 해서 값을 가져온다.



MyBatis 소스

	{call PROC_BL_TO_UTM(#{latitude,mode=IN,jdbcType=VARCHAR},#{longitude,mode=IN,jdbcType=VARCHAR},#{utmx,mode=OUT,jdbcType=DECIMAL},#{utmy,mode=OUT,jdbcType=DECIMAL})}


statementType을 "CALLABLE"로 설정해주면 procedure를 호출하게 된다.  parameterType 에는 클래스 파일을 지정해주고 직접 파라미터 부분에 들어올 타입에 대한 세팅을 하게 된다.

vo.ProcVO.java
public class ProcVO {
	
	private String latitude = "";
	private String longitude = "";
	private String utmx = "";
	private String utmy = "";
	... 이하 getter/setter


이건 그냥 데이터를 옮기기위한 빈즈 파일

실제호출 java
ProcVO proc = new ProcVO();
proc.setLatitude("37.539421");
proc.setLongitude("127.047852");

session.update("myBatis.mappers.UserMapper.testProc", proc);

System.out.println("utmx : "+proc.getUtmx()+" utmy : "+proc.getUtmy());


자바쪽에서는 기존처럼 넘겨주면 된다. map 대신 클래스파일에 데이터를 담아주기만 하면 된다.
결과 코드 역시 자바클래스에서 getter로 받아오면 완료.

parameterMap으로 되어있는 기존의 소스들이 많다면 일일이 클래스를 만들어줘야 하기에 마이그레이션에 애로사항이 좀 있을수 있겠지만. 어차피 관리 측면에서도 빈파일로 관리하는쪽이 좋기 때문에. 이번기회에 싹 정리 하는것이 미래를 위해서는 좀더 낫지 않을까 싶다.

이전에 iBatis 에서 테스트 할때 자바빈파일로 파라미터를 매핑하는경우.. 프로시저가 정상적인 호출이 안되서 map으로 작업했던 거였는데.. iBatis가 원래 그런건지;; 내가 잘못했던 것인지 모르겠다...
정확한 답을 아시는분이 있다면 코멘트로~~~


저작자 표시 비영리 동일 조건 변경 허락
신고

Comment +6


저번 포스팅에서 iBatis 에서 myBatis로 넘어오면서 바뀐점들에 대해 적었었다.
2010/11/05 - [Java & iBatis] - iBatis에서 myBatis로 개요 및 변경점

이 포스트에서는 이전에 바뀐 것들을 바탕으로 기본 환경 설정을 확인 해본다.

프로젝트 환경 설정은 그림과 같다.


플렉스쪽이 더 있기는 하지만 그건 여기서는 중요한건 아니므로 패스 하고. Java, MyBatis 만 확인 해보자.

Configration.xml


<configuration>


<typealiases>
<typealias type="vo.UserVO" alias="User">
</typealias></typealiases>
<environments default="development">
<environment id="development">
<transactionmanager type="JDBC">
<datasource type="POOLED">
<property value="oracle.jdbc.driver.OracleDriver" name="driver"></property>
<property value="db_url" name="url"></property>
<property value="user" name="username"></property>
<property value="passwd" name="password"></property>
</datasource>
</transactionmanager></environment>
</environments>
<mappers>
<mapper resource="myBatis/mappers/UserMapper.xml">
</mapper></mappers>
</configuration>





빈즈(여기서는 플렉스와 맞추기위해서 VO로 작업했다)의 typeAlias 가 먼저 나오고 환경설정 그다음에 mapper가 나온다.  이 순서대로 넣지 않고 typeAlias를 environments 다음에 넣거나 하면 에러가 발생한다.
에러내용에 보면 순서 정의가 되어있고 그 순서에 맞춰서 넣어야 한다고 되어있다.

Description Resource Path Location Type
The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?,mappers?)". Configuration.xml taskManager/WebContent/WEB-INF/classes/myBatis line 6 XML Problem

properties 에서 시작해서 mapper 까지 순서가 정해져 있는데 xml을 위에서 부터 읽어서 뒤에정의된 내용은 덮어 쓰게 되므로 설정파일에서는 미리정의 해놓은것 같다. (이전포스트에서 속성을 덮어쓰는 순서에 대해서 이야기 한적이 있다)

MyBatisManager.java

public class MyBatisManager {
	
	public static SqlSessionFactory sqlMapper = null;
	
	public static SqlSessionFactory getInstance(){
		if(sqlMapper == null) {
			try {
				String resource = "myBatis/Configuration.xml";
				Reader reader = Resources.getResourceAsReader(resource);
				sqlMapper = new SqlSessionFactoryBuilder().build(reader);
				reader.close();
				
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return sqlMapper;
	}
}


SqlSessionFactory는 어플리케이션과 같은 라이프사이클을 가지게 되므로 싱글톤으로 간단하게 구현해놓는다.
이후에 getInstance()를 호출해서 클래스의 참조를 받아오게 된다.
매니저로 구현하지 않고 그냥 java 파일의 상단에서 생성시켜도 별 상관은없다.

UserDao.java

public class UserDao {
	
	public static SqlSessionFactory sqlMapper = MyBatisManager.getInstance();
	
	public List getUserList() {
		
		List list = new ArrayList();
		
		SqlSession session = sqlMapper.openSession();
		try {
			list = session.selectList("myBatis.mappers.UserMapper.getUserList");
			
		} catch (Exception e){
			e.printStackTrace();
		} finally {
			session.close();
		}
		
		return list;
	}
}


상단에서 SqlSessionFactory 객체를 가져오고 SqlSession을 오픈하고 mapper의 네임스페이스를 호출해서 쿼리를 실행시킨다.

UserMapper.xml


<mapper namespace="myBatis.mapper.UserMapper">

<select id="getUserList" resulttype="User"> SELECT userID, name, phone, email, TO_CHAR(regdate,'YYYY-MM-DD HH24:MI') regdate, isuse, auth FROM TR_USER ORDER BY REGDATE DESC</select>
</mapper>

nameSpace가 풀 경로인것을 확인한다.  resultType에는 Configure.xml 에서 typeAlias에서 지정해놓은 shortName 으로 설정한다. 네임스페이스와 실행시킬 쿼리아이디를 합해서 UserDao.java에서 호출하게 된다.


순서를 살펴 보면..

UserDao가 실행되면서 MyBatisManager 에서 Configure.xml 파일의 설정을 참조해서 SqlSessionFactory를 생성하고 Factory에서 session을 열고 UserMapper의 쿼리를 실행시킨다.

플렉스에서 받아들이는쪽은 기존의 iBatis 설정과 같으니 패스 하기로 하고 마무리~
첨부된 소스는 위에서 설명된 파일들이다.

 src.zip


저작자 표시 비영리 동일 조건 변경 허락
신고

Comment 1


원래 마이그레이션 포스팅부터 다룰려고 했으나.. 이게 공식위키에서는 엄청 쉽게 이야기 한것과 달리 그냥 라이브러리 교체 정도로 끝나는게 아니라서 일단 바뀐 용어와 개요부터 정리를 좀 해야 할 필요성을 느꼈다.

myBatis로 바뀌면서 기본 용어들이 조금씩 차이가 나기 때문에.. 주의가 필요하다.

기존 SqlMapConfig은 Configration로 변경되었고 sqlMap은 mapper로 변경되었다. 다른 용어들이 변경된 상황이나.. 내부적으로 사용하는 것들(ex. isEqual 을 아에 if 로 바꾼거라던지)을 보면 좀더 범용적으로 알아보기 쉽게 바꿔가는 것을 목표로 가고있는 듯 하다.
익숙해지면 아무래도 코드 읽기도 만들기도 쉬울것으로 보인다.

큰 변화중 하나는 자바 애노테이션을 사용해서 xml을 사용하지 않고 모든것을 자바로만 할수 있게 되었다.
물론 Configration.xml 도 자바에서 직접 DataSource,  Environment 등을 선언해서 클래스화 시킬수 있다. xml 스트링으로 설정값등을 저장해야 한다는 것에 부담을 느꼈다면 좋은 변화라고 할수 있겠다.

주의할점은 xml로 Configure를 만들고 환경변수와 property를 클래스로도 만들었다면.. 클래스쪽이 나중에 읽어지게 되서 xml로 되어있는 세팅이 자바 클래스에서 선언해놓은것으로 덮어써지게 된다. 혼란을 줄수 있으니 한가지 방법만으로 프로젝트를 구성하는것이 좋을것이다.

그리고 Configuration configuration = new Con.... 형식으로 선언을 하고 나서는 mapper도 xml이 아니고 configuration.addMapper(UserMapper.class) 형식으로 추가 해야 하기 때문에 어느쪽으로 할것인지 확실하게 결정을 하고 나서 진행해야 한다.

네임스페이스
방식도 변경되었는데.. sqlMap 파일별로 줄여놓은 이름을 사용했다면 이제 풀경로로 사용하게 된다. 공식 설명서에서는 혼란을 줄이고 어떤것이 호출되는지 정확하게 알수 있으니 좋다라고 해놨지만 아무래도 길어지니 쓰기에 불편하기는 하다..
기존에 <sqlMap namespace="User"> 이렇게 쓰던것을
<mapper namespace="myBatis.mapper.UserMapper"> 이렇게 풀 경로로 쓰게 된다.

실제 자바쪽에서 호출할때도
list = session.selectList("myBatis.mappers.UserMapper.getUserList");

이렇게 길게 호출 하게 되는데.. 그냥 string 이라서 입력이 여간 불편하다.

이런 경우에 위에서 이야기한 자바 애노테이션 (@Select)을 사용해서 mapper 파일을 xml이 아니고 자바로 만들어놓으면 코드힌트까지 사용해서 편하게 쓸수있다.
UserMapper mapper = session.getMapper(UserMapper.class);
list = mapper.selectUserList();

권장사항은 xml 이라고 되어있었던거 같은데.. 편하기는 자바쪽이 편한 구조랄까..;;




기본 용어

SqlSessionFactory :  SqlMapClient가 SqlSessionFactory로 변경되었다. 어플리케이션과 같은 라이프사이클을 가지게 된다. 한번만 생성되면 되므로 Manager 클래스에서 싱글톤으로 구현하면 된다.

SqlSessionFactoryBuilder : 환경 값(디비 및 트랜잭션 설정등..)을 읽어와서 SqlSessionFactory 인스턴스를 만들어준다. 기존의 SqlMapClientBuilder 대신 사용된다.

String resource = "org/mybatis/example/Configuration.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);

SqlSession : SqlSessionFactory 에서 세션을 하나씩 열어서 개별 쓰레드 별로 사용한다. 세션을 열고나서 실제 쿼리를 수행하게 된다. 하나의 리퀘스트에 하나의 세션을 가지게 되고 사용후에는 꼭 닫아줘야 한다.

mapper : 기존의 sqlMap이 변경된 것이다. 실제 쿼리들이 들어있게 되고 위의 SqlSession을 열어야 호출할 수 있다. method scope를 가지게 되고 해당 메서드가 사용되고나면 사라진다. 별도로 닫거나 할 필요는 없고 SqlSession이 함께 관리 한다.
SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    // do work
} finally {
    session.close();
}


변경되거나 추가된 속성들

기존에 조건에 따라 변하는 쿼리를 만들기 위해서 사용되던 태그들이 변경되었다. 조금더 직관적으로 바뀌었고 해당상황(Update, Select)등에 맞춰서 사용할 수 있는 태그들도 추가되었다.

parameterMap은 더이상 사용하지 않게 되었다. parameterMap과 parameterClass 대신 parameterType 하나로 사용한다.
resultMap은 여전히 남아있지만 resultClass 는 resultType 으로 변경되었다.
parameterType과 resultType에는 기본형(int, byte, .... )부터 클래스 명까지 기존처럼 사용할 수 있다.

기존에 procedure를 호출하기 위해 사용하던 <procedure>가 사라지고 statementType 속성이 생겼다. PREPARED, STATEMENT, CALLABLE 중에 하나를 선택할 수 있고 기본값은 PREPARED이다.

파라미터를 매핑하기위해서 사용하던 #var# 형태는 #{var} 로 바뀌었다. $var$ 역시 ${var} 형태로 사용하면 된다.
 
참고) #{var}와 ${var}의 차이는 prepredStatement의 파라미터로 사용할 것인가.. 그냥 String 값으로 때려박을것인가 하는 것이다. order by 같은 경우에 사용하기 위해서는 order by ${orderParam} 처럼 사용해야 한다. 이 방법을 사용하는 경우 myBatis가 자체적으로 쿼리의 적합성여부를 판단할 수 없기 때문에 사용자의 입력값을 그대로 사용하는 것보다는 개발자가 미리 정해놓은 값등으로 변경하도록 해서 정확한값이 들어올수 있도록 해야 한다.


sqlMap쪽에서 사용하던 typeAlias가 sqlMap이 바뀐 mapper 에서 사용되지 않고 Configration 파일에서 정의하도록 변경되었다.

<typeAliases>
    <typeAlias type="vo.UserVO" alias="User"/>
</typeAliases>

Configration 파일에 위의 형식처럼 Aliase를 정의하면 전체 mapper 에서 사용할 수 있다.



Dynamic Statement의 변화

<isEqual> , <isNull> 등의 구문이 <if>로 통합되었다. 이전보다는 확실히 직관적으로 쓸수 있을듯 하다.
<if test="userID != null"> 형태로 간단하게 사용할 수 있다. (스트럿츠2에서 사용하는 형태 처럼 보이는데..;;)

<dynamic > 형태로 해서 where 조건절이나 and , or 를 동적으로 만들던것이 <where>나 update에서 사용할 수 있는 <set> 등으로 변경되었다.

<select id="getUserList" resultType="User>
    SELECT * FROM TR_USER
        <where>
            <if test="isAdmin != null">
                authLevel = '1'
             </if>
          </where>
</select>

trim, foreach 태그가 새로 추가 되었다.
trim은 쿼리를 동적생성할때에 쿼리를 연결하기 위해서 컴마(,)를 사용한경우 마지막항목이 조건을 만족하지 못해서 생성된 쿼리 끝에 컴마가 붙어있다던가 하는 경우에 잘라낼 수 있다.
foreach는 반복적인 항목을 동적으로 넣을때 사용할 수 있다. ( ex. where 조건절에서 in 을 사용하는 경우)

공식홈페이지의 위키에 기존 iBatis를 myBatis로 바꿀때 확인해야 할 부분들이 있으니 꼭 참고 하자.
http://code.google.com/p/mybatis/wiki/DocUpgrade3

ps.
지금 있는것도 못하고 있는데 항상 새로운 버전이 쏟아지니 미칠꺼같다 -ㅅ-;;
Flex4도 정식으로 손대보지 못했는데 5 소식이라니.. ㅠㅠ
저작자 표시 비영리 동일 조건 변경 허락
신고

Comment +6

  • 재미있네요.. iBATIS를 안써본지 어언.... 6개월을 넘어서는거 같습니다만..
    나도 모르게 myBATIS가 나오다니요 ㅋ

    그나저나 프로필 사진은.... 너무 야윈거 아닌가요!?

    금새 홀쭉해지셨네....-ㅅ -; 모쪼록 추위 조심하시길..

    • 실물보다 더 좀 그렇게 나온거같아서 포샵이라도 할까 새로 사진을 찍어볼까 고민중이다 ㅎㅎ

      살이 좀 빠지긴 했지 운동은 안하고 -ㅅ- 짱박혀 있으니;

  • '-' 2011.03.08 14:41 신고

    담아갑니다! 감사합니다!

  • 좋은글이네요~ 잘봤습니다!

  • 희윤동모 2012.09.16 21:12 신고

    담아갑니다.. ^^ 좋은 글 감사합니다.

  • 콤콤 2013.10.02 16:47 신고

    혹시 order by ${orderParam} 이렇게 사용할 경우
    사용자가 지정한 값이 들어가게 설정해야 한다고 하셨는데
    어떤 방법이 있는지 알려주실수 있으신가요?ㅎㅎ;;




보통 자바환경에서 iBatis를 사용중이라면 log4j를 기본 로거로 많이 사용하게 되는데..
단순 자바 어플 만들면서 이것저것 추가하고 하는게 귀찮다면..

log4sql 을 사용해보자.

간단하지만 성능은 완벽!

PreparedStatement 에 파라미터가 어떻게 들어가서 실행되는지 확인 해보는 것에는 이것만큼 좋은게 없는것 같다.. trace 에서 출력되는 쿼리를 바로 실행할수 있고 어떤것이 파라미터이고 어떤것이 statement인지 구별할수 있는 구분자도 포함되어있다.

일단 다운로드

사용법

다운로드 받은 파일의 압축을 풀면 log4sql.jar 파일이 있다.. 로그확인이 필요한 프로젝트의 라이브러리에 등록한후에 드라이버 경로를 바꿔준다.

자바 내부에서 정의 했다면 String oracleDriver = "oracle.jdbc.driver.OracleDriver"; 형식으로 되어있을꺼고
iBatis를 사용한다면 <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/> 이런식으로 컨피그 xml에 정의되어있을것이다.

이 경로를 'core.log.jdbc.driver.OracleDriver' 이렇게만 바꿔주면 끝..

별도의 설정을 할 수 있게 압축 파일 내부에 log4sql_conf.jsp 파일이 있어서 웹프로젝트일때는 동적으로 설정을 바꿀수 있도록 제공하지만 로그만 보기 위해서는 드라이버만 바꿔주면.. 쿼리 관련 로그들이 전부 출력된다.

세부 설정에서 내가 개발중인 패키지만 등록해서 해당 패키지에서 나오는 로그만 출력되도록 설정할수도 있고. SQL의 순수 실행시간만을 계산해주기 때문에 쿼리 자체의 퍼포먼스 테스트에도 유용하다.

MSSQL, Oracle, Cubrid, PostgreSql, Infomix 등등.. 현존하는 거의 모든 디비를 지원하고.. 비동기 모드도 지원한다.. 

참고]  http://log4sql.sourceforge.net/index_kr.html
저작자 표시 비영리 동일 조건 변경 허락
신고

Comment 0



아이바티스가 3으로 버전업 되면서 구글그룹으로 합류하고 이름이 myBatis로 변경되었다.
공식 홈페이지도 http://www.mybatis.org/ 로 변경되었고.. 2010년 8 월에 3.02 버전이 나왔다.
이전에 DTD가 http://www.ibatis.com 으로 되어있어서 에러가 난다면.. http://apache.ibatis.com 으로 변경하면 된다고 한다.

기존 버전사용자의 마이그레이션은 간단하다고 하는데.. 기존에 운영하던 프로젝트를 버전업 해보고나서 포스팅 예정이다.


iBatis를 사용해서 프로시저를 호출하는 것은 다른 statement(select, update.. )를 호출하는 것처럼 간단하다..
문제는 파라미터의 세팅이다. 호출이야 <procedure> 태그만 적어주면 되는데 파라미터가 꽤나 귀찮게 하는 경우가 생긴다.

1. 자바에서 호출하는 경우

자바에서 호출하는 경우는 CallableStatement 를 사용하게 된다.

CallableStatement cstmt = conn.prepareCall("{call PROC_BL_TO_UTM(?,?,?,?)}");
cstmt.setString(1, "37.465687");
cstmt.setString(2, "127.249481");
cstmt.registerOutParameter(3, OracleTypes.FLOAT);
cstmt.registerOutParameter(4, OracleTypes.FLOAT);
cstmt.execute();
uTmx = cstmt.getFloat(3);
uTmy = cstmt.getFloat(4);

in 파라미터와 out 파라미터를 구분해서 넘겨주고 execute 시키면 가뿐하게 넘어온다.

2. iBatis에서 프로시저 호출하기

SqlMap 설정

<parameterMap class="map" id="blParam">
  <parameter property="p_latitude" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
  <parameter property="p_longitude" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
  <parameter property="p_utmx" jdbcType="DECIMAL" javaType="long" mode="OUT"/>
  <parameter property="p_utmy" jdbcType="DECIMAL" javaType="long" mode="OUT"/>
 </parameterMap>
  
 <procedure id="bl_to_utm" parameterMap="blParam">
  <![CDATA[
   {call PROC_BL_TO_UTM(?,?,?,?)}
  ]]>
 </procedure>


java 설정

Map map = new HashMap();
map.put("p_latitude",vo.getX_latitude());
map.put("p_longitude", vo.getX_longitude());
sqlMapper.update("VocIphone.bl_to_utm", map );

String utmx = map.get("p_utmx").toString();
String utmy = map.get("p_utmy").toString();


SqlMap 쪽에서 parameterMap 으로 설정해놓은 형식으로 프로시저에 전달되고 리턴은 데이터를 실어서 날렸던 맵으로 돌아온다..
sqlMapper를 실행시킬때 update / queryForObject / queryForList 를 사용할수 있으니 리턴 타입에 맞춰서 사용하면 된다.

out을 리스트로 받는 경우 resultMap을 설정해서 List 형태로도 받을수 있다.

<parameter property="result" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" resultMap="resultParam" mode="OUT"/>

resultMap을 설정해주고 resultMap에서 property와 column이름을 설정해주고 class를 미리 만들어놓은 VO객체로 넣어주면 해당항목의 리스트로 프로시저 실행결과가 리턴된다.

3. 주의사항

sqlMap에서 프로시저를 호출할때

<procedure id="bl_to_utm" parameterMap="blParam">
   {
     call PROC_BL_TO_UTM(?,?,?,?)
    }
 </procedure>

위의 코드처럼 중괄호를 적어놓으면 에러가 난다..;; 괜히 보기 편하게 만든다고 했다가 삽질하게 된다.

파라미터의 타입

만약 프로시저의 파라미터가 Number 타입이라면.. OUT 파라미터 정의에서 Number라고 쓰면 에러가 난다.....;;;
오라클의 경우 프로시저 내부에서 Number를 BigDecimal로 변환해서 사용한다고 한다. 따라서 아래처럼 적으면 에러가 난다.

<parameter property="p_utmy" jdbcType="NUMBER" javaType="java.util.Number" mode="OUT"/>ERROR


<parameter property="p_utmy" jdbcType="DECIMAL" javaType="long" mode="OUT"/>

이런 형태로 적어줘야 정상적으로 실행된다. 이것때문에 하루를 꼬박 구글링과 삽질로 보냈다..
오라클 디비를 내가 만든것도 아니고 이런걸 어떻게 알지..-ㅅ-;;

iBatis로 할수 있는게 참 많다.. Result 를 받는 시점에서 rowHandler를 설정해서 xml 트리형태의 데이터를 한방에 가져올수도 있고... 복잡한 파라미터와 조건에 맞춘 쿼리도 쉽게 뽑아내준다..
iBatis 파이팅 -ㅅ-!?;;
저작자 표시 비영리 동일 조건 변경 허락
신고

Comment 1

  • bluebird 2011.11.22 00:06 신고

    궁금한게있습니다. 위예제에서 프로시저에서 넘어온 out 변수를 맵에 담았는데요
    자바빈즈에 프로퍼티명을줘서 자바빈즈에 담기게 할수는 없나요?

    <parameterMap class="패키지명.자바빈즈" id="blParam">
    <parameter property="빈즈 프로퍼티명" jdbcType="DECIMAL" javaType="long" mode="OUT"/>

    이런식으로 작성했을때 프로시저 호출은되도 out변수에 담긴값이 빈즈의 프로퍼티에 세팅이
    안되더라구요;;