Mybatis 쿼리를 바인딩된 String으로 가져오는 방법

마이바티스에서 수행되어 만들어진 쿼리를 추출하고 싶을 때 사용합니다.

@Autowired SqlSession sqlSession 을 사용합니다.

1. Mapper.xml 에 쿼리가 아래와 같다고 가정하고

<select id=”selectTest“>
select *
from test
where idx1 = #{param.idx1}
and idx2 = #{param.idx2}
and userid = #{param.session.userid}
and testList in (
<foreach collection=”param.testList” item=”testList” separator=”,”>
#{testList}
</foreach>
)
</select>

2. 파라미터를 HashMap 형식일 경우(기본적으로 모두 String형으로 할랍니다 “”)

//인터페이스 샘플입니다. 아래와 같다고 가정하고
List selectTest(@Param(“param”) Map param);

//파라미터가 아래와 같이 오브젝트로 구성된다고 합시다.
param : {
idx1 : “001”
, idx2 : “002”
, session : {
userid : “aaboo”
}
, testList: [“a”, “b”]
}

3. 쿼리를 추출해야할 샘플코드는 아래와 같습니다.

//파라미터를 수동으로 만들어 봅니다.(실제에서는 불필요한…)
 HashMap param= new HashMap(); //최종 param
 HashMap paramValue= new HashMap();
 HashMap sessionValue = new HashMap();
 sessionValue.put("userid", "aaboo");
 paramValue.put("idx1", "001");
 paramValue.put("idx2", "002");
 paramValue.put("session", sessionValue);
 param.put("param", paramValue);

/*
실제에서는 param을 한번 감싸줘야 합니다
HashMap param= new HashMap();
param.put("param", [전체 파라미터를 모은 Map]);
*/

//쿼리 바인딩 준비 
BoundSql boundSql = sqlSession.getConfiguration().getMappedStatement("selectTest").getBoundSql(param); 

 //파라미터가 ?로 표시된 쿼리
 String query = boundSql.getSql(); 
 /* 결과값
select *
from test
where idx1 = ?
and idx2 = ?
and userid =  ?
and testList in (?, ?)
 */ 

 // query의 ? 순서대로 나열된 리스트
 List parameterMapping = boundSql.getParameterMappings(); 

 /* 결과값
["param.idx1", "param.idx2", "param.session.userid", "__frch_testList_0", "__frch_testList_1"]
 */ 

//쿼리의 ?를 parameterMapping으로 replace해줍니다.
for(ParameterMapping pm : parameterMapping){
   //pm.getProperty() >> "param.session.userid"와 같이 나옵니다.
   String sPm = pm.getProperty();
   if(sPm.indexOf("__frch_")>-1){
      //__frch_testList_0 > param.testList_0
      sPm = sPm.replaceFirst("\\_\\_frch\\_", "param.");
      sPm = sPm.replaceFirst("\\_", "."); //param.testList_0 > param.testList.0
   }   

   //param.session.userid 을 .으로 split(쪼개면)합니다. tParam.length=2
   String[] tParam = sPm.getProperty().split("\.");

   Object tValue = param; //오브젝트에 param대입
   //쪼개진 tParam[]을 순차적으로 돌면서 tValue를 얻고자 합니다.
   for(int i=0, il=tParam.length; i<il; i++){
      try{
         //toJson으로 텍스트형으로 바꾸고, 다시 HashMap 형태로 fromJson 해줬습니다.
         tValue = gson.fromJson(gson.toJson(((Map<String, Object>) tValue).get(tParam[i])), HashMap.class);
      }catch(Exception e1){
         try{
            tValue = (String) gson.fromJson(gson.toJson(((Map<String,Object>)tValue).get(tParam[i])), ArrayList.class);
         }catch(Exception e2){
            try{
               tValue = (String) ((ArrayList<Object>) tValue).get(Integer.parseInt(tParam[i]));
            }catch(Exception e3){
               tValue = (String) ((Map<String,Object>) tValue).get(tParam[i]); 
               //마지막의 String이 들어갈 겁니다.
            }
         }
      }
   }
    //구해진 tValue를 query에다 넣어 줍니다. 
    query = query.replaceFirst("\?", "'"+ tValue +"'");   
} 

 System.out.println(query); 
 //결과값 
select * 
from test 
where idx1 = '001' 
and idx2 = '002' 
and userid =  'aaboo'
and testList in ('a','b')


댓글 남기기