'FrameWork'에 해당되는 글 2건

  1. 2015.03.04 iBatis에서 AutoResultMap Error 해결방법
  2. 2012.10.17 iBATIS 간단한 Tip..
2015.03.04 13:15
이번에 다이나믹 쿼리를 이용하여 간단히 데이터 배치작업을 하려고 만든 프로그램에서 에러가 발생했다.
평소엔 SQL-MAP 파일에 SQL Injection이 발생할 수 있는 코드는 사용하지 않았기 때문에 이런 문제가 발생하지 않았는데 배치작업을 위해 여러 테이블에서 두루 사용하기 위한 쿼리문을 등록하려다 보니 자연히 SQL Injection이 발생될 수 있는(보안상 안좋은) 쿼리를 등록해서 사용하게 되었다.

문제의 쿼리는 아래와 같았다.
<select id="getList" parameterClass="map" resultClass="java.util.HashMap">
SELECT
<iterate property="fieldName" prepend=",">
$fieldName[]$
</iterate>
FROM
$tableName$
WHERE
$condition$
</select>
여러 테이블을 조회하기 때문에 파라미터로 입력되는 모든 값들이 변경될 수 있다.
호출은 아래와 같이 했다.
List fieldList = new ArrayList();
fieldList.add("foo");
fieldList.add("bar");
Map map = new HashMap();
map.put("tabeName", "Hello");
map.put("condition", "idx > 0");
map.put("fieldName", fieldList);
List<Map> result = sqlMapClient.queryForList("map-id.getList", map);
위의 코드가 한번만 호출이 된다면 아무런 문제가 없이 해결이 된다.
하지만 아래와 같이 fieldList와 tableName이 변경하여 다시 조회하면 에러가 발생한다.

List fieldList = new ArrayList();
fieldList.add("foo2");
fieldList.add("bar2");
Map map = new HashMap();
map.put("tabeName", "Hello2");
map.put("condition", "idx > 0");
map.put("fieldName", fieldList);
List<Map> result = sqlMapClient.queryForList("map-id.getList", map);
이는 iBatis에서 SQL-ID가 한번 실행되면 쿼리의 Meta Data를 캐쉬하고 있기 때문으로 다음번에 호출되었을 때 이미 캐쉬에 저장된 foo, bar 필드를 쿼리결과에서 찾는데 필드가 없기 때문(foo2, bar2가 존재할 뿐)에 에러를 리턴하게 된다. MetaData의 캐쉬를 하지 않으려면 쿼리를 다음과 같이 변경해야 한다.

<select id="getList" parameterClass="map" resultClass="java.util.HashMap" remapResults="true">
SELECT
<iterate property="fieldName" prepend=",">
$fieldName[]$
</iterate>
FROM
$tableName$
WHERE
$condition$
< /select>

http://kamkami.tistory.com/102

'FrameWork' 카테고리의 다른 글

iBatis에서 AutoResultMap Error 해결방법  (0) 2015.03.04
iBATIS 간단한 Tip..  (0) 2012.10.17
Posted by 물색없는세상
2012.10.17 14:35

SqlMaps를 작성할때, 종종 SQL의 일부가 중복되곤한다. 예를 들어, FROM절이나 제약조건등이 그렇다. iBATIS는 이러한 중복되는 SQL문의 일부를 재사용하기 위한 강력한 태그를 제공한다. iBATIS사용시 대개 다음처럼 작성할것이다.

<select id="selectItemCount" resultClass="int">
  SELECT COUNT(*) AS total
  FROM items
  WHERE parentid = 6
</select>

<select id="selectItems" resultClass="Item">
  SELECT id, name
  FROM items
  WHERE parentid = 6
</select>

여기서는 FROM절 이하가 모두 중복이다. 이 중복을 제거하기 위해서, <sql> 과 <include> 태그를 사용한다. <sql> 태그는 재사용하기 위한 조각을 포함한다. <include> 태그는 이러한 조각을 포함한다.

<sql id="selectItem_fragment">
  FROM items
  WHERE parentid = 6
</sql>
<select id="selectItemCount" resultClass="int">
  SELECT COUNT(*) AS total
  <include refid="selectItem_fragment"/>
</select>
<select id="selectItems" resultClass="Item">
  SELECT id, name
  <include refid="selectItem_fragment"/>
</select>

<include> 태그는 명명공간을 인식한다. 그래서 당신은 다른 map에 위치한 조각들도 참조할수 있다(어쨌든 iBATIS가 SqlMaps를 로드하는 방식에 따라, 포함된 조각은 statement를 포함하기 전에 로드될것이다). 조각은 파라미터처럼 사용될수 있기 때문에 쿼리-수행시 포함되고 처리된다.

<sql id="selectItem_fragment">
  FROM items
  WHERE parentid = #value#
</sql>
<select id="selectItemCount" parameterClass="int" resultClass="int">
  SELECT COUNT(*) AS total
  <include refid="selectItem_fragment"/>
</select>
<select id="selectItems" parameterClass="int" resultClass="Item">
  SELECT id, name
  <include refid="selectItem_fragment"/>
</select>

http://harurun.blog.me/120055300736

'FrameWork' 카테고리의 다른 글

iBatis에서 AutoResultMap Error 해결방법  (0) 2015.03.04
iBATIS 간단한 Tip..  (0) 2012.10.17
Posted by 물색없는세상