본문 바로가기
Mybatis

mybatis XML에 쿼리자체를 동적쿼리로 적용하여 실행하고 싶은 경우 (+ibatis)

by 모닝위즈 2021. 12. 30.
반응형

Spring 5 + Mybatis 3.2.8 + Mybatis-spring 1.2.1 기준임.

 

일반적인 쿼리  XML 


<!-- 쿼리 실행 -->
<select id="getThisResult" resultType="java.util.LinkedHashMap" >
    <![CDATA[
        SELECT A.*
        FROM TB_ARTICLES  A
        WHERE ROWNUM <= 100000
    ]]>
</select>
 

쿼리를 실행할 경우 동적 쿼리로 실행하고 싶을 경우가 있음.

 

예를 들어 아래와 같은 경우 

 

1. 쿼리 자체를 아래와 같이 직접 넘겨서 실행하고 싶을 경우

String query = "SELECT 1 FROM DUAL";

<!-- 동적 쿼리 실행 -->
<select id="getQueryResult" resultType="java.util.LinkedHashMap" parameterType="java.lang.String">
    <![CDATA[
        SELECT A.*
        FROM ( #{query} ) A
        WHERE ROWNUM <= 100000
    ]]>
</select>
 

 

2. 위와 같이 실행할 때 문제가 되는 점. 


<!-- 동적 쿼리 실행 -->
<select id="getQueryResult" resultType="java.util.LinkedHashMap" parameterType="java.lang.String">
    <![CDATA[
        SELECT A.*
        FROM ( 'SELECT 1 FROM DUAL' ) A
        WHERE ROWNUM <= 100000
    ]]>
</select>
 

위와 같은 형식이 되기 때문에, 홑따옴표가 붙어서 에러가 남.

 

3. 그렇다면, #{}가 아닌 ${}로 처리를 하면 될까?

 

그 부분도 마찬가지로 데이터타입으로 인해 실행되지 않는다. 

 

 

4. 아래와 같이 ${}로 처리를 하되 Object로 넘거야 한다. 


public class SqlToolMngVO implements Serializable {

   private static final long serialVersionUID = 4008156682073033724L;

   Object obj;

   public Object getObj() {
      return obj;
   }

   public void setObj(Object obj) {
      this.obj = obj;
   }
} 

 


<!-- 동적 쿼리 실행 -->
<select id="getQueryResult" resultType="java.util.LinkedHashMap"
        parameterType="kr.co.sekorea.application.mng.sqltool.vo.SqlToolMngVO">
    <![CDATA[
        SELECT A.*
        FROM ( ${obj} ) A
        WHERE ROWNUM <= 100000
    ]]>
</select>
 

 

위와 같이 처리를 해주면 실행이 됨.

 

5. 아래 그림은 해당 부분을 위해 만든 실행 결과 화면임.

 

 

 

 

 위 화면에서의 다른 처리적인 부분은 입맛에 맞추면 됨.

 화면의 textarea에 적용된 에디터는 codemirror-5.53.2 버전을 이용하여 만듦.

 

 

6. 혹시 사용하시고 계시는 프레임워크가 Mybatis가 아닌 Ibatis일 경우는 아래와 같이 해주어야함.


<!-- 동적 쿼리 실행 -->
<select id="getQueryResult" resultClass="java.util.LinkedHashMap" remapResults="true">
    <![CDATA[
        SELECT A.*
        FROM ($query$) A
        WHERE ROWNUM <= 100000
    ]]>
</select>
 

remapResults를 설정해주어야됨. 그렇지 않을 경우 쿼리자체를 동적 쿼리로 실행하였을 때, 해당 쿼리로 적용이 되어 다른 쿼리로 실행을 하려면 재기동을 해야함. 그렇기 때문에 해당 옵션을 추가해줌으로써 문제해결.  

댓글