마이바티스에서 수행되어 만들어진 쿼리를 추출하고 싶을 때 사용합니다.
@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')