oracle MyBatis에서 다중 Insert 하는 방법



mssql에서 oracle로 마이그레이션을 하는 도중 하나의 맵핑된 쿼리 안에서


여러개의 행을 insert하는 것에서 문제가 발생했다


mssql을 사용할떈 그냥 insert문을 여러개 쓰는것 만으로 한번에 여러 행을 입력 할 수 있었는데


오라클에선 구문오류가 발생하게 된다.


그렇게 방법을 찾다가 발견한 방법은


INSERT ALL 이다



사용법은 아주아주 굉장히 간단하다.


일단 MyBatis에서 여러 데이터를 맵형태로 보내 다이나믹 쿼리로 만드는 방법은


아래 링크를 참고하고

2015/07/09 - [Yame Programmer/전자정부프레임워크] - [ibatis] 동적쿼리 생성 및 outOfBoundsException 에러


ibatis와 mybatis의 사용방법이 상이하긴 하지만 맥락은 같으니 참고하면 좋을 것이다.




쿼리문은 아래와 같이 사용 하면 된다.


1
2
3
4
5
6
7
8
9
10
    <insert id="insertMtrlOrderList" parameterType="java.util.Map">
        <foreach collection="list" item="item" index="index"  open="INSERT ALL " separator=" " close="SELECT * FROM DUAL" 
         into FM_MATERIALS_ORDER_LIST(MTRL_ID, MTRL_ORDER_ID, 
            MTRL_ENTERPRISE, UNIT_COST, MTRL_ORD_QUANTITY, APPLY_DATE)
        values
            (#{item.MTRL_ID}, #{item.MTRL_ORDER_ID}, 
        #{item.MTRL_ENTERPRISE}, #{item.UNIT_COST}, 
        #{item.MTRL_ORD_QUANTITY}, SYSDATE)
        </foreach>
    </insert>
cs



시작할떄 INSERT ALL 을 써주고 본 쿼리으 insert문은 insert를 제외한 into부터 시작해서 작성하면 끝


역시 사람은 아는게 많아야 손발이 고생을 안하는 것 같다.




간단하다 mybatis에 써놓은 쿼리중에 #{변수} << 이부분 이름 틀린거


예를들어 VO엔


1
2
3
4
5
6
7
8
9
    private String FLOOR_PEOPLE;//
    
    public String getFLOOR_PEOPLE() {
        return FLOOR_PEOPLE;
    }
    public void setFLOOR_PEOPLE(String fLOOR_PEOPLE) {
        FLOOR_PEOPLE = fLOOR_PEOPLE;
    }
 
cs


이렇게 되어있는데


쿼리 작성시엔 아래와 같이 대소문자를 다르게 썻다던가


1
2
3
4
5
UPDATE EASY_COMMON.CM_FLOOR_INFO
        SET 
            FLOOR_NAME = #{FLOOR_NAME},
            FLOOR_PEOPLE = #{FLOOR_people}
        WHERE FLOOR_ID = #{FLOOR_ID}
cs


혹은 다른 이름을 썻다던가 할때 발생하는 에러이다.


한꺼번에 특정 문자열을 바꾸는 작업후에 발견되는 경우가 종종 있다.


org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'EASY_COMMON' in 'class egovframework.easyplatform.common.place.space.vo.SpaceVO'

at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) ~[mybatis-spring-1.2.0.jar:1.2.0]

at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:364) ~[mybatis-spring-1.2.0.jar:1.2.0]

at com.sun.proxy.$Proxy84.selectList(Unknown Source) ~[?:?]

at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:194) ~[mybatis-spring-1.2.0.jar:1.2.0]

at egovframework.rte.psl.dataaccess.EgovAbstractMapper.selectList(EgovAbstractMapper.java:238) ~[egovframework.rte.psl.dataaccess-3.5.0.jar:?]

at egovframework.easyplatform.common.setting.standardsetting.service.impl.SpaceSettingServiceImpl.insertSpace(SpaceSettingServiceImpl.java:30) ~[classes/:?]

at egovframework.easyplatform.common.setting.standardsetting.web.SpaceSettingController.insertSpace(SpaceSettingController.java:71) ~[classes/:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_91]

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_91]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_91]

at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_91]

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:747) ~[spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:676) ~[spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) [spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) [spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) [spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at javax.servlet.http.HttpServlet.service(HttpServlet.java:650) [servlet-api.jar:?]

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) [spring-webmvc-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) [servlet-api.jar:?]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [catalina.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.69]

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat7-websocket.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.69]

at egovframework.easyplatform.common.interceptor.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:26) [classes/:?]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.69]

at egovframework.rte.ptl.mvc.filter.HTMLTagFilter.doFilter(HTMLTagFilter.java:52) [egovframework.rte.ptl.mvc-3.5.0.jar:?]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.69]

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.0.9.RELEASE.jar:4.0.9.RELEASE]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.69]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.69]

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.69]

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.69]

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) [catalina.jar:7.0.69]

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) [catalina.jar:7.0.69]

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.69]

at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) [catalina.jar:7.0.69]

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.69]

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436) [catalina.jar:7.0.69]

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) [tomcat-coyote.jar:7.0.69]

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) [tomcat-coyote.jar:7.0.69]

at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) [tomcat-coyote.jar:7.0.69]

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_91]

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_91]

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.69]

at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]

Oracle 부적합한 열유형 null 처리 jdbcType=VARCHAR를 사용하지 않고 해결하는 방법


mssql로 만들어진 프로젝트를 Oracle로 마이그레이션 작업을 하던 도중 어마어마한 노가다 작업에 봉착했다


Oracle 사용시 Null 허용컬럼에 값이 null이 들어가는 경우


부적합한 열 유형 이라는 에러 메세지가 뜨게 된다.


이때 이를 해결하기 위해서 


value1 = #{value1, jdbcType=VARCHAR},

value2 = #{value2, jdbcType=VARCHAR}


이런식으로 값 뒤에  , jdbcType=VARCHAR]  를 붙이게 되는데 


생각해보니 이게 양이 너무나도 많은것이다. 이걸 하나하나 언제 다 수정하고 앉아있을까


그래서 구글링해서 찾아낸 방법이 있다.


단 이것은 자신이 mybatis 설정파일을 변경할 권한이 있는 경우 사용하길 바란다.



1. mybatis-config.xml 파일을 연다. 만약 없는 경우

전자정부 프레임워크를 사용한다면 context-sqlMap.xml 파일을 열어 보면


1
2
3
4
5
6
7
8
9
10
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:/egovframework/sqlmap/example/sql-map-config.xml" />
        <!-- <property name="mapperLocations" value="classpath:/egovframework/sqlmap/example/sample/PostgreSQL.xml" />
        
        <property name="configLocation" value="classpath:/mapper/mybatis-config.xml" /> -->
        <!-- Core File관련 Table SQL MAP 설정 위치 -->
        <!-- DB변동시 sql 맵퍼 패턴 수정 -->
        <property name="mapperLocations" value="classpath:/egovframework/sqlmap/example/mappers/${Globals.Mapping}"    /
    </bean>
cs



이런 부분이 있는데 여기서  프로퍼티 네임이 configLocation 인것을 찾는다


value값에 보면 컨피그로케이션의 경로가 있는데 저 경로에 찾아가면


아마 mybatis 설정하는 부분이 있거나 typeAlias를 선언해 주는 부분일텐데 일단 해당 파일을 연다




2. configuration 태그 아래 settings 이라는 태그가 있는지 확인


3. 없으면 직접 설정한다


4. 있던 없던 아래와 같은 셋팅 프로퍼티를 추가 한다.


1
2
3
4
5
6
<!--  oracle null 처리  -->
    <settings>
        <setting name="cacheEnabled" value="false" />
        <setting name="jdbcTypeForNull" value="NULL" />
    </settings>
 
cs




그럼 이제 저 귀찮음 많은 jdbcType=VARCHAR 선언들을 해주지 않아도 된다!


역시 개발자는 귀찮은거 싫어하고 머리를 굴려야 한다는걸 다시 깨닫게 된다.


쿼리를 작성하다 보면 부등호 (>,<) 를 사용해야 할 때가 있다. 그러나 mybatis에서 사용하면 에러가 나는데


이때 해결방법을 알아 보자.




쿼리에 부등호 기호를 사용하면  


The content of elements must consist of well-formed character data or markup.


라는 경고문구가 나타나기도 한다.


부등호 이외에도 '&' 같은 특수기호에서도 나타난다


이때 해결방법은 간단하다


<![CDATA ]]> 를 사용하면 된다.



1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="loadCartList"  parameterType="userInfoVO" resultType="cartVO">
    
    <![CDATA
    SELECT
        *    
    FROM
        table_name
    WHERE
        coulumA < 10
    AND 
        coulumB > 4
    ]]>
    </select>
cs



이렇게 쿼리를 CDATA로 감싸주면 된다.


혹은


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<select id="loadCartList"  parameterType="userInfoVO" resultType="cartVO">
    
    SELECT
        *    
    FROM
        table_name
    
    WHERE
    <![CDATA
        coulumA < 10
    AND 
        coulumB > 4
    ]]>
    </select>
cs




이런 식으로 사용 할 수도 있다.



방금 댓글을 남겨주신 분이 추가 정보를 달아주셨다


> - &gt;
< - &lt;
>= - &gt;=
<= - &lt;=


CDATA를사용하지 않고 저렇게 HTML에서 사용하던 방식으로도 치환이 가능 하다



1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="loadCartList"  parameterType="userInfoVO" resultType="cartVO">
    
    SELECT
        *    
    FROM
        table_name
    
    WHERE
        coulumA &lt; 10
    AND 
        coulumB &gt; 4
    </select>
 
cs


+ Recent posts