<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>빛을 담고 세상 넓히기</title>
	
	<link>http://fantazic.com</link>
	<description>마음의 빛으로 넓은 세상을 비추고 싶다. JAVA, 고양이, 사진들이 있는 곳.</description>
	<pubDate>Fri, 10 Jul 2009 08:22:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-nc-sa/2.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/fantazic" type="application/rss+xml" /><feedburner:browserFriendly>Welcome. This is RSS of Fantazic Blog using UTF-8.</feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>톰캣 한글 인코딩 문제와 관련된 코드들</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/Wu3v5iLe3pQ/255</link>
		<comments>http://fantazic.com/archives/255#comments</comments>
		<pubDate>Fri, 10 Jul 2009 06:03:17 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[인코딩]]></category>

		<category><![CDATA[톰캣]]></category>

		<category><![CDATA[한글]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=255</guid>
		<description><![CDATA[Java로 6년째 개발을 하면서 한글 문제는 더 이상 새로운 것이 없겠지 생각을 하지만 매번 알 수 없는 상황에 부딪히게 된다.
EUC-KR 기반의 아파치-톰캣 시스템에서 브라우져 주소창의 한글을 처리하려고 할 때 다음과 같은 문제가 발생했다.
주소창에 &#8216;http://v.daum.net/search?q=한글&#8217;을 직접 입력하는 경우 크게 3가지 경우가 발생했다.
1) &#8216;한글&#8217;이라는 파라미터 값이 &#8216;EUC-KR&#8217;로 URLEncoding 되서 넘어오는 경우
2) &#8216;한글&#8217;이라는 파라미터 값이 &#8216;UTF-8&#8242;로 URLEncoding 되서 [...]]]></description>
			<content:encoded><![CDATA[<p>Java로 6년째 개발을 하면서 한글 문제는 더 이상 새로운 것이 없겠지 생각을 하지만 매번 알 수 없는 상황에 부딪히게 된다.</p>
<p>EUC-KR 기반의 아파치-톰캣 시스템에서 브라우져 주소창의 한글을 처리하려고 할 때 다음과 같은 문제가 발생했다.</p>
<p>주소창에 &#8216;http://v.daum.net/search?q=한글&#8217;을 직접 입력하는 경우 크게 3가지 경우가 발생했다.</p>
<p>1) &#8216;한글&#8217;이라는 파라미터 값이 &#8216;EUC-KR&#8217;로 URLEncoding 되서 넘어오는 경우<br />
2) &#8216;한글&#8217;이라는 파라미터 값이 &#8216;UTF-8&#8242;로 URLEncoding 되서 넘어오는 경우<br />
3) &#8216;한글&#8217;이 bytes로 변환되서 넘어오는 경우</p>
<p>이와 유사한 문제가 아파치 rewrite module을 사용할 때도 발생했다. 예를 들어 &#8216;http://v.daum.net/한글&#8217;을 &#8216;http://v.daum.net/search?q=한글&#8217;로 재작성하는 경우 &#8216;한글&#8217;이 bytes로 변환된다.</p>
<p>이에 대한 해결방법은 여러가지가 있을 수 있는데, 다음과 같은 아이디어를 기반으로 문제를 해결했다.</p>
<p>1. URLEncoding된 문자열의 헥사값을 bytes로 변환할 수 있다.<br />
2. bytes의 인코딩을 예측할 수 있다.</p>
<p>(구현된 코드는 톰캣 내부의 파라미터 처리 부분과 Daum 검색개발팀의 황재석님의 코드에 도움을 받았습니다.)</p>
<p>&#8216;getParameterSafely(request.getQueryString(), &#8220;q&#8221;);&#8217;와 같이 사용하면 됩니다. 단, 파라미터에 &#8216;%&#8217; 문자가 포함된 경우 오작동하게 됩니다.</p>
<pre>
/* public query parsing method */
public static String getParamterSafely(String queryString, String key) {
  if (StringUtils.isEmpty(queryString)) {
    return "";
  }

  try {
    String safeQueryString = urlDecodeSafely(queryString);
    return getParameter(safeQueryString, key);
  } catch (UnsupportedEncodingException e) {
    //ignore
    e.printStackTrace();
  }
  return "";
}

/* URLDecoding 수행 */
private static String urlDecodeSafely(String queryString)
  throws UnsupportedEncodingException {
  if (StringUtils.isEmpty(queryString))
    return "";
  byte[] src = queryString.getBytes("ISO-8859-1");
  byte[] bytes = urlDecode(src);
  String charset = guessCharset(bytes);
  return new String(bytes, charset);
}

/* 헥사코드를 bytes로 변환 */
private static byte[] urlDecode(byte[] data)
  throws UnsupportedEncodingException {
  int ix = 0;
  int ox = 0;
  while (ix < data.length) {
    byte c = data[ix++];
    switch ((char) c) {
      case '+':
        data[ox++] = (byte) ' ';
        break;
      case '%':
        data[ox++] = (byte) ((convertHexDigit(data[ix++]) << 4)
          + convertHexDigit(data[ix++]));
        break;
      default:
        data[ox++] = c;
    }
  }

  return ArrayUtils.subarray(data, 0, ox);
}

/* 헥사코드 변환 */
private static byte convertHexDigit(byte b) {
  if ((b >= '0') &#038;&#038; (b <= '9'))
    return (byte) (b - '0');
  if ((b >= 'a') &#038;&#038; (b <= 'f'))
    return (byte) (b - 'a' + 10);
  if ((b >= 'A') &#038;&#038; (b <= 'F'))
    return (byte) (b - 'A' + 10);
  return 0;
}

/* 재석님의 캐릭터셋 추측하는 메소드 */
private static String guessCharset(byte[] bytes) {
  try {
    CharsetDecoder decoder = Charset.forName("MS949").newDecoder();
    ByteBuffer bb = ByteBuffer.wrap(bytes);
    decoder.decode(bb);
    bb.clear();
    return "MS949";
  } catch (Exception e) {
    return "UTF-8";
  }
}

/* 쿼리 문자열에서 특정 키의 값을 가져온다. */
private static String getParameter(String safeQueryString, String key) {
  String parameters[] = safeQueryString.split("&#038;");
  if (parameters != null) {
    for (String parameter : parameters) {
      if (parameter.startsWith(key + "=")) {
        return parameter.replaceFirst(key + "=", "");
      }
    }
  }
  return "";
}
</pre>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/Wu3v5iLe3pQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/255/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/255</feedburner:origLink></item>
		<item>
		<title>지리산 스님들의 못 말리는 수행 이야기</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/rHwdaIAV4J8/252</link>
		<comments>http://fantazic.com/archives/252#comments</comments>
		<pubDate>Tue, 02 Jun 2009 01:04:50 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[깨달음으로 가는 길]]></category>

		<category><![CDATA[보리심]]></category>

		<category><![CDATA[스님]]></category>

		<category><![CDATA[지리산]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=252</guid>
		<description><![CDATA[속세의 인연으로 항상 많은 도움을 받고 있는 스님들의 이야기가 책으로 나왔다.
나의 채식 생활을 처음 접하는 분들이 가장 많이 하는 질문이 &#8216;왜 채식을 하세요?&#8217;인데, 이 질문에 이렇게 대답을 하곤 한다.
&#8216;가족분들이 출가를 하셨고, 그 모습을 가까이서 살펴보니 참 좋아보이더라. 특히 채식은 쉽게 할 수 있으며 내 삶에 많은 도움이 되는 것 같아서 채식을 하기로 결심했다.&#8217;
스님과의 인연으로 &#8216;보리심의 [...]]]></description>
			<content:encoded><![CDATA[<p>속세의 인연으로 항상 많은 도움을 받고 있는 스님들의 이야기가 책으로 나왔다.</p>
<div id="attachment_253" class="wp-caption alignnone" style="width: 300px"><a href="http://www.yes24.com/24/goods/3416655" target="_blank"><img src="http://fantazic.com/wp-content/uploads/2009/06/l.jpg" alt="지리산 스님들의 못 말리는 수행 이야기" title="지리산 스님들의 못 말리는 수행 이야기" width="290" height="400" class="size-full wp-image-253" /></a><p class="wp-caption-text">지리산 스님들의 못 말리는 수행 이야기</p></div>
<p>나의 채식 생활을 처음 접하는 분들이 가장 많이 하는 질문이 &#8216;왜 채식을 하세요?&#8217;인데, 이 질문에 이렇게 대답을 하곤 한다.</p>
<blockquote><p>&#8216;가족분들이 출가를 하셨고, 그 모습을 가까이서 살펴보니 참 좋아보이더라. 특히 채식은 쉽게 할 수 있으며 내 삶에 많은 도움이 되는 것 같아서 채식을 하기로 결심했다.&#8217;</p></blockquote>
<p>스님과의 인연으로 <a href="http://borisim.net/">&#8216;보리심의 새싹&#8217;</a> 블로그를 만드는데 조그만 도움을 드렸는데, 그곳의 글들이 모여 하나의 책으로 나오게 되었다.</p>
<p>지리산의 소소한 삶, 항상 행복한 모습, 내면의 변화 그리고 결심. 작지만 소중한 이야기들이 이 책에 담겨있다. 많은 분들이 이 책을 통해 답답한 마음을 잠시 잊고, 보다 근본적인 내면의 변화를 경험해볼 수 있기를 바란다.</p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/rHwdaIAV4J8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/252/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/252</feedburner:origLink></item>
		<item>
		<title>슬프지만 피할 수 없는 현실</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/khk9M3vTccY/249</link>
		<comments>http://fantazic.com/archives/249#comments</comments>
		<pubDate>Mon, 25 May 2009 09:04:35 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[깨달음으로 가는 길]]></category>

		<category><![CDATA[사람]]></category>

		<category><![CDATA[죽음]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=249</guid>
		<description><![CDATA[노무현 대통령의 서거 소식 후 마음이 심란하다.
독재자 박정희를 모방하고 있는 이명박 정부와 한나라당. 그 끝은 어디일까?
대규모 토목건설, 언론통제, 사상통제, 암살, 전시행정&#8230;
결국 목적은 장기집권일까? 부정부패일까?
죽은 사람은 말이 없고 죽음은 돌이킬 수 없는 현실이 되어버렸다.
너무나 당연한 것들이 당연하지 않은 세상. 슬프다.
]]></description>
			<content:encoded><![CDATA[<p>노무현 대통령의 서거 소식 후 마음이 심란하다.</p>
<p>독재자 박정희를 모방하고 있는 이명박 정부와 한나라당. 그 끝은 어디일까?</p>
<p>대규모 토목건설, 언론통제, 사상통제, 암살, 전시행정&#8230;</p>
<p>결국 목적은 장기집권일까? 부정부패일까?</p>
<p>죽은 사람은 말이 없고 죽음은 돌이킬 수 없는 현실이 되어버렸다.</p>
<p>너무나 당연한 것들이 당연하지 않은 세상. 슬프다.</p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/khk9M3vTccY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/249/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/249</feedburner:origLink></item>
		<item>
		<title>돌아온 제비, 하지만 이곳은 위험한 곳</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/ziaajwACIIA/230</link>
		<comments>http://fantazic.com/archives/230#comments</comments>
		<pubDate>Wed, 22 Apr 2009 11:23:58 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[깨달음으로 가는 길]]></category>

		<category><![CDATA[GMC]]></category>

		<category><![CDATA[유리]]></category>

		<category><![CDATA[제비]]></category>

		<category><![CDATA[하우스킬]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=230</guid>
		<description><![CDATA[제주도 중산간에 위치한 사무실 창문 밖에는 덩그러니 제비집 두개가 자리잡고 있었다. 서울에서 제비를 못 보게 된지 벌써 10년은 된 것 같은데 과연 이곳에는 제비가 돌아올까 싶었는데 봄이 되자 제비들이 찾아왔고 사무실 앞 둥지에도 한쌍의 제비가 자리를 잡았다.
새로 도착한 제비 부부는 열심히 집을 수리하더니 지금은 하루 종일 벌레 사냥을 다니고 있고 가끔 둘이 집에 모여 신나게 [...]]]></description>
			<content:encoded><![CDATA[<p>제주도 중산간에 위치한 사무실 창문 밖에는 덩그러니 제비집 두개가 자리잡고 있었다. 서울에서 제비를 못 보게 된지 벌써 10년은 된 것 같은데 과연 이곳에는 제비가 돌아올까 싶었는데 봄이 되자 제비들이 찾아왔고 사무실 앞 둥지에도 한쌍의 제비가 자리를 잡았다.</p>
<div id="attachment_238" class="wp-caption alignnone" style="width: 460px"><a href="http://fantazic.com/wp-content/uploads/2009/04/home1.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/home1.jpg" alt="지난 겨울 동안 비어 있던 제비집" title="제비집" width="450" height="290" class="size-full wp-image-238" /></a><p class="wp-caption-text">지난 겨울 동안 비어 있던 제비집</p></div>
<p>새로 도착한 제비 부부는 열심히 집을 수리하더니 지금은 하루 종일 벌레 사냥을 다니고 있고 가끔 둘이 집에 모여 신나게 수다를 떨기도 한다.</p>
<div id="attachment_234" class="wp-caption alignnone" style="width: 460px"><a href="http://fantazic.com/wp-content/uploads/2009/04/female.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/female.jpg" alt="집을 지키는 암컷 제비" title="암컷 제비" width="450" height="362" class="size-full wp-image-234" /></a><p class="wp-caption-text">집을 지키는 암컷 제비</p></div>
<div id="attachment_235" class="wp-caption alignnone" style="width: 460px"><a href="http://fantazic.com/wp-content/uploads/2009/04/male.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/male.jpg" alt="잠시 쉬고 있는 수컷 제비" title="수컷 제비" width="450" height="323" class="size-full wp-image-235" /></a><p class="wp-caption-text">잠시 쉬고 있는 수컷 제비</p></div>
<p>그런데 제비가 자리를 잡고 몇일이 지났을 때 작지만 큰 사고가 하나 발생했다. 사무실 옥상을 날라다니던 제비 한 마리가 쿵! 소리를 내며 유리에 충돌했고 배를 위로 하고 바닥에 쓰려져 정신을 잃은 것이다. 깜짝 놀라 살펴보니 의식을 잃었던 제비가 다행이도 잠시 후 정신을 차리고 하늘로 날라갔다.</p>
<p>그 날은 구름이 많고 하늘이 흐린 날이였는데 아마 창문에 비친 하늘을 진짜 하늘로 착간했던 것 같다. 작은 생명체가 그렇게 힘 없이 다치는 모습을 다시는 보고 싶지 않아 유리창에 신문지를 붙여 놓았으나 변화무쌍한 제주도 날씨에 몇일을 버티지 못하고 신문지는 다 떨어져나간 상태다.</p>
<div id="attachment_236" class="wp-caption alignnone" style="width: 460px"><a href="http://fantazic.com/wp-content/uploads/2009/04/window.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/window.jpg" alt="한라산이 바라 보이는 사무실 창문" title="사무실 창문" width="450" height="300" class="size-full wp-image-236" /></a><p class="wp-caption-text">한라산이 바라 보이는 사무실 창문</p></div>
<p>사실 현대적 건물은 아름다움을 위해 다양한 재료를 사용하는데 특히 유리를 사용한 건물이 많아지고 있는 것 같다. 그 유리의 투명한 아름다움이 인간에게 얼마만큼의 행복감을 주는지 짐작은 가지만 그 아름다움이 작은 생물들에게 얼마나 많은 고통과 위험을 안겨주고 있는지 생각하면 마음이 아파진다. 이러한 아름다움은 조용한 덫과 같다고 할까?</p>
<div id="attachment_231" class="wp-caption alignnone" style="width: 410px"><a href="http://fantazic.com/wp-content/uploads/2009/04/gmc.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/gmc.jpg" alt="예쁜 외관의 GMC 빌딩" title="Daum GMC" width="400" height="300" class="size-full wp-image-231" /></a><p class="wp-caption-text">예쁜 외관의 GMC 빌딩</p></div>
<p>아름다운 Daum GMC 건물은 수학여행 온 학생들이 견학을 하고 갈 정도로 멋지게 유리로 외관을 꾸민 대표적인 건물이다. 하지만 이곳에는 사람들이 알지 못하는 많은 사연이 있을지도 모른다. 지난 1월 15일 잠시 바람을 쐬러 나왔던 나는 회사 정문 앞에 쓰러져 있는 새를 발견했다. 처음에는 새가 겨울을 이겨내지 못하고 영양실조로 지쳐 쓰러져 있는지 알았는데 사무실로 데리고 온 새의 입에서 피가 흐르는 것을 보니 유리벽에 충돌해서 죽음의 위기를 맞이한 것임을 직감할 수 있었다.</p>
<div id="attachment_233" class="wp-caption alignnone" style="width: 460px"><a href="http://fantazic.com/wp-content/uploads/2009/04/hurt.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/04/hurt.jpg" alt="피를 많이 흘린 호랑지빠귀" title="호랑지빠귀" width="450" height="338" class="size-full wp-image-233" /></a><p class="wp-caption-text">피를 많이 흘린 호랑지빠귀</p></div>
<p>다행이도 이 호랑지빠귀는 <a href="http://www.wildanimals.or.kr/">(사)한국야생동물보호협회</a>에서 오신 분들이 구조해 갔고 치료를 받은 후 자연으로 돌아간 것으로 알고 있다.</p>
<p>인간은 자연 진화의 법칙을 뛰어넘는 매우 빠른 속도의 발전을 계속하고 있다. 인간의 힘은 지구의 지형을 바꾸고 환경을 변화시키고, 이 변화의 속도에 적응할 수 없는 생명체들의 죽음과 멸종을 앞당기고 있다. 하지만 이런 절망적인 상황에서도 무언가 우리가 할 수 있는 일들이 있지 않을까? 차가운 비극을 줄일 수 있는 따스함이 우리에게 남아있지 않을까?</p>
<p>마음이 많이 아프지만 그래도 희망을 잃고 싶지 않다.</p>
<p><strong>(참고 자료)</strong></p>
<ul>
<li><a href="http://www.wildlifeprotection.net/everything/actionalertbirds.html">미국에서 1년 동안 약 10억 마리의 새가 유리에 충돌해서 죽는다고 합니다.</a> 이를 방지하기 위한 방법도 설명되어 있네요.</li>
<li><a href="http://www.scienceblog.com/community/older/2002/F/20022503.html">건물의 불을 끄면 약 83%의 충돌을 막을 수 있다고 합니다.</a></li>
<li><a href="http://www.auduboninternational.org/PDFs/WHM-%20Preventing%20Bird%20Window%20Collisions.pdf">새들의 창문 충돌을 막는 방법(PDF)</a></li>
</ul>
<p>정리하자면 다음과 같은 방법으로 새의 죽음을 줄일 수 있다.</p>
<ol>
<li>새가 다친 흔적이 있으면 그 원인을 조사한다.</li>
<li>새 모이통을 빌딩 가깝게 또는 멀리 떨어진 곳에 설치한다.</li>
<li>유리의 반사를 줄일 수 있는 다양한 방법을 시도한다.</li>
<li>높은 빌딩인 경우 밤에 소등한다.</li>
<li>위의 조치가 성공적인지 확인한다. 만일 부상당한 새를 발견하면 <a href="http://www.wildanimals.or.kr/">야생동물보호협회</a>에 연락한다.</li>
</ol>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/ziaajwACIIA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/230/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/230</feedburner:origLink></item>
		<item>
		<title>iBatis에서 batch 기능 활용하기</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/VotgN5FeA-E/228</link>
		<comments>http://fantazic.com/archives/228#comments</comments>
		<pubDate>Tue, 07 Apr 2009 00:19:40 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[batch]]></category>

		<category><![CDATA[iBatis]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=228</guid>
		<description><![CDATA[iBatis는 아래와 같은 방법으로 batch 처리가 가능하다.  iBatis 내부 코드를 확인해 본 바로는 PreparedStatement.addBatch()를 사용하고 있고, 동일한 쿼리가 반복해서 들어올 때 하나의 batch로 처리해준다.

try {
  SqlMapClient.startTransaction();
  SqlMapClient.startBatch();
  while (...) {
    SqlMapClient.insert(query, params);
  }
  SqlMapClient.executeBatch();
  SqlMapClient.commitTransaction();
} catch (Exception e) {
  log.error(e, e);
} finally {
  [...]]]></description>
			<content:encoded><![CDATA[<p>iBatis는 아래와 같은 방법으로 batch 처리가 가능하다.  iBatis 내부 코드를 확인해 본 바로는 PreparedStatement.addBatch()를 사용하고 있고, 동일한 쿼리가 반복해서 들어올 때 하나의 batch로 처리해준다.</p>
<pre>
try {
  SqlMapClient.startTransaction();
  SqlMapClient.startBatch();
  while (...) {
    SqlMapClient.insert(query, params);
  }
  SqlMapClient.executeBatch();
  SqlMapClient.commitTransaction();
} catch (Exception e) {
  log.error(e, e);
} finally {
  SqlMapClient.endTransaction();
}
</pre>
<p>이 기능을 활용해서 BatchManager를 만들어서 사용하고 있는데, 사용자의 로그인 시간을 기록하거나 게시물의 조회수를 늘리는 등 <strong>빈번하게 동일한 update가 발생하는 서비스에 사용하면 효과</strong>가 있다.</p>
<p>사용법은 기존의 서비스 코드 수정을 최소화하는 방법으로 고안했다. SqlMapClient.insert(query, params)를 BatchManager.insert(query, params)로 수정하면 된다.</p>
<p><strong>관련 코드)</strong><br />
BatchManager.java</p>
<pre>
public class BatchManager {
  private static BatchWorker worker = BatchWorker.getInstance();
  static {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        try {
          worker.flushAll();
          worker.stop();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  public static void insert(String query, Object params) {
    worker.put(new BatchQuery(INSERT, query, params));
  }

  public static void update(String query, Object params) {
    worker.put(new BatchQuery(UPDATE, query, params));
  }
}
</pre>
<p>BatchWorker.java</p>
<pre>
public class BatchWorker {
  public static final int HEARTBEAT = 1000;
  public static int MAX_WAIT = 30000;
  public static final int SIZE_OF_ONE_BATCH = 200;
  public static final int MAX_SIZE = 100;
  private long lastTime;
  private final Timer timer;
  private Vector<BatchQuery> queue;
  private static BatchWorker singletonWorker;

  private BatchWorker() {
    lastTime = System.currentTimeMillis();
    timer = new Timer(true);
    queue = new Vector<BatchQuery>();
    startWorker();
  }

  public static synchronized BatchWorker getInstance() {
    if (singletonWorker == null)
      singletonWorker = new BatchWorker();
    return singletonWorker;
  }

  private void startWorker() {
    timer.scheduleAtFixedRate(new TimerTask() {
      @Override
      public void run() {
        try {
          doBatch();
        } catch (Exception e) {
          // ignore
          e.printStackTrace();
        }
      }
    }, 0, HEARTBEAT);
  }

  private void doBatch() {
    if (System.currentTimeMillis() - lastTime > MAX_WAIT
      || queue.size() >= MAX_SIZE) {
      executeQuery();
      lastTime = System.currentTimeMillis();
    }
  }

  private synchronized void executeQuery() {
    if (queue.size() == 0)
      return;
    try {
      int cnt = 0;
      SqlMapClient.startTransaction();
      SqlMapClient.startBatch();
      while (cnt++ < SIZE_OF_ONE_BATCH) {
        if (queue.size() == 0)
          break;
        BatchQuery batchQuery = queue.remove(0);
        switch (batchQuery.type) {
          case INSERT:
            SqlMapClient.insert(batchQuery.query, batchQuery.params);
            break;
          case UPDATE:
            SqlMapClient.update(batchQuery.query, batchQuery.params);
            break;
          default:
            break;
        }
      }
      SqlMapClient.executeBatch();
      SqlMapClient.commitTransaction();
    } catch (Exception e) {
      log.error(e, e);
    } finally {
      SqlMapClient.endTransaction();
    }
  }

  public int size() {
    return queue.size();
  }

  public void put(BatchQuery query) {
    queue.add(query);
  }

  public void flushAll() {
    while (queue.size() > 0)
      executeQuery();
  }

  public void stop() {
    timer.cancel();
  }
}
</pre>
<p>BatchQuery.java</p>
<pre>
public class BatchQuery {
  public enum QueryType {
    INSERT, UPDATE
  }

  public String query;
  public Object params;
  public QueryType type;

  public BatchQuery(QueryType type, String query, Object params) {
    this.type = type;
    this.query = query;
    this.params = params;
  }
}
</pre>
<p><strong>참고)</strong></p>
<ul>
<li>Oracle10g 환경에서는 batch로 처리할 경우 쿼리 수행은 빨라지나 batch 처리마다 쿼리 파싱이 발생해서 CPU 비용은 증가하는 경우도 보였다.</li>
<li>예전에 찾아본 바로는 한번에 만건 이상도 batch 처리가 가능하다고 한다. 환경에 따라 가장 효율적인 batch 크기를 결정해야 한다.</li>
<li>batch 처리할 경우 수행속도가 빨라지는 장점이 있고 transaction lock이 적게 잡혀 DB 부담을 줄여주는 효과도 있다.</li>
</ul>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/VotgN5FeA-E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/228/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/228</feedburner:origLink></item>
		<item>
		<title>iBatis 환경에서 DB 유닛 테스트를 위한 팁</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/nWRYwJ3XLo8/222</link>
		<comments>http://fantazic.com/archives/222#comments</comments>
		<pubDate>Tue, 24 Mar 2009 11:21:48 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[iBatis]]></category>

		<category><![CDATA[TestCase]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=222</guid>
		<description><![CDATA[최근에는 새로운 기능을 개발할 때 test case를 먼저 작성하는 경우가 많다. 특히 DB와 연동되는 기능을 개발할 경우 다양한 종류의 실수로 작업이 지연될 수 있기 때문에 unit test를 꼭 먼저 작성하고 개발을 시작한다.
하지만 일반적인 개발환경에서 테스트 데이터가 DB에 직접 쌓이게 되면 데이터가 꼬이는 경우가 발생할 수 있어서 이를 해결할 방법이 필요하다. 예를 들어 게시판에 글을 쓰고, [...]]]></description>
			<content:encoded><![CDATA[<p>최근에는 새로운 기능을 개발할 때 test case를 먼저 작성하는 경우가 많다. 특히 DB와 연동되는 기능을 개발할 경우 다양한 종류의 실수로 작업이 지연될 수 있기 때문에 unit test를 꼭 먼저 작성하고 개발을 시작한다.</p>
<p>하지만 일반적인 개발환경에서 테스트 데이터가 DB에 직접 쌓이게 되면 데이터가 꼬이는 경우가 발생할 수 있어서 이를 해결할 방법이 필요하다. 예를 들어 게시판에 글을 쓰고, 수정하고, 지우는 기능을 테스트하면서 오류로 글이 지워지지 않고 남는 경우가 있을 수 있고, 새로운 데이터를 입력하는 테스트인 경우 unique key 제한에 걸려 매번 테스트 데이터를 수정해야 하는 불편함이 따를 수 있다.</p>
<p>이 문제를 피해가기 위해 여러가지 방법을 활용할 수 있는데 Spring에서는 <a href="http://whiteship.tistory.com/170">AbstractTransactionalSpringContextTests</a>와 같은 방식으로 이를 해결하고 있다. iBatis 환경에서는 다음과 같이 JUnit4의 기능을 활용해서 DB unit test를 편하게 할 수 있다.</p>
<pre>
public class TransactionalTestCase {

  @BeforeClass
  public static void create() {
    SqlMapClient.startTransaction();
  }

  @AfterClass
  public static void destroy() {
    SqlMapClient.endTransaction();
  }

  protected ResultSet executeQuery(String sql) throws SQLException {
    Connection conn = SqlMapClient.getConnection();
    Statement st = conn.createStatement();
    return st.executeQuery(sql);
  }

  protected int executeUpdate(String sql) throws SQLException {
    Connection conn = SqlMapClient.getConnection();
    Statement st = conn.createStatement();
    return st.executeUpdate(sql);
  }

  protected int countTableRows(String tableName) throws SQLException {
    int count = 0;
    ResultSet rs = executeQuery("select count(*) from " + tableName);
    while (rs.next()) {
      count = rs.getInt(1);
    }
    return count;
  }

  protected void deleteTable(String tableName) throws SQLException {
    executeUpdate("delete from " + tableName);
  }
}
</pre>
<p>기본적으로 클래스의 시작과 끝에 Transaction을 걸어주고 있고, 데이터 초기화 기능 및 간단한 테이블 조회 기능을 추가했다. 각자의 환경에 따라 세부적인 코드는 변할 수 있겠지만 이 코드를 바탕으로 쉽게 DB unit test를 할 수 있는 기회가 될 수 있기를 바란다.</p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/nWRYwJ3XLo8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/222/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/222</feedburner:origLink></item>
		<item>
		<title>블로거뉴스 개발자로 살아가기</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/-cWJPxCy9TA/217</link>
		<comments>http://fantazic.com/archives/217#comments</comments>
		<pubDate>Sat, 21 Mar 2009 13:48:05 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[깨달음으로 가는 길]]></category>

		<category><![CDATA[발표]]></category>

		<category><![CDATA[블로거뉴스]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=217</guid>
		<description><![CDATA[다음 입사 후 블로거뉴스 개발을 담당한지 6개월이 되었고 이제는 생각해 오던 것들이 조금씩 실질적인 결과로 나타나고 있다. 처음에 떠올랐던 많은 생각들이 지금은 고민과 실험을 통해 대부분 정리가 되었고 지금은 큰 방향을 정한 상태에서 세부적인 내용들을 구현하고 있다.
지난 주에는 &#8216;블로거뉴스 제작 발표회&#8217;에서 개발팀에서 고민하고 있는 내용들을 발표할 기회가 있었고 현재 진행 중인 다양한 시도들을 공유하고 의견을 [...]]]></description>
			<content:encoded><![CDATA[<p>다음 입사 후 블로거뉴스 개발을 담당한지 6개월이 되었고 이제는 생각해 오던 것들이 조금씩 실질적인 결과로 나타나고 있다. 처음에 떠올랐던 많은 생각들이 지금은 고민과 실험을 통해 대부분 정리가 되었고 지금은 큰 방향을 정한 상태에서 세부적인 내용들을 구현하고 있다.</p>
<p>지난 주에는 <a href="http://chitsol.com/entry/%EB%8B%A4%EC%9D%8C-%EB%B8%94%EB%A1%9C%EA%B1%B0%EB%89%B4%EC%8A%A4%EC%9D%98-%EC%83%88%EC%9D%B4%EB%A6%84%EC%9D%80-%EB%8B%A4%EC%9D%8C-%EB%B7%B0">&#8216;블로거뉴스 제작 발표회&#8217;</a>에서 개발팀에서 고민하고 있는 내용들을 발표할 기회가 있었고 현재 진행 중인 다양한 시도들을 공유하고 의견을 들을 수 있었다. <em>(이미지는 <a href="http://caranddriving.net/1085">카앤드라이빙님의 블로그</a>에서 빌려왔습니다.)</em></p>
<div id="attachment_218" class="wp-caption alignnone" style="width: 310px"><a href="http://fantazic.com/wp-content/uploads/2009/03/dsc_0715.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/03/dsc_0715-300x199.jpg" alt="블로거뉴스 개발팀의 벽을 뛰어 넘는 시도들" title="블로거뉴스 - Beyond the Boundary" width="300" height="199" class="size-medium wp-image-218" /></a><p class="wp-caption-text">블로거뉴스 개발팀의 벽을 뛰어 넘는 시도들</p></div>
<p>발표 내용은 <a href="http://highconcept.tistory.com/588">하이컨셉님이 자세히 정리한 글</a>을 참고하면 좋을 것 같다. 간단히 설명하자면 새롭게 변화하는 변화의 중심은 RDB 기반에서 검색엔진 기반으로 변화하면서 검색 엔진의 랭킹을 사용자의 참여를 통해 구현하는 &#8216;열린편집 엔진&#8217;, 사용자의 행위, 문맥, 관계 등을 분석해서 글을 추천하는 &#8216;개인화&#8217; 그리고 API 와 위젯을 기반으로 한 롱테일 블로그 활성화라고 할 수 있다. 하이켄셉님은 이번 시도를 <a href="http://health20.kr/331">&#8216;컨텍스트 웹&#8217;</a>으로 해석했는데 오히려 개발할 때는 몰랐던 다양한 시도들의 근간이 되는 철학이 이미 존재하고 있음을 알게 되었다.</p>
<p>앞으로 또 다시 6개월이 지나면 현재 구현하고 있는 새로운 변화의 결과를 볼 수 있을 것이다. 과연 상상하고 있는 것과 만들어진 결과가 얼마나 차이가 있을지, 새로운 문화를 만들 수 있을지 기대반 걱정반이다.</p>
<p>개발자 앞에서 발표는 여러 번 했었지만 다양한 배경의 블로거들 앞에서 발표를 하니 마음만 앞서서 말을 급하게 했던 것 같다. 특히 전날 저녁에 농구 시합을 뛰고, 제주에서 서울로 이동을 하고, 또 홍대에서 발표 전에 가볍게 농구 한게임을 하고 왔더니 몹시 피곤해 보이는 것 같다.</p>
<div id="attachment_219" class="wp-caption alignnone" style="width: 310px"><a href="http://fantazic.com/wp-content/uploads/2009/03/dsc_0718.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/03/dsc_0718-300x199.jpg" alt="발표하는 모습" title="발표하는 모습" width="300" height="199" class="size-medium wp-image-219" /></a><p class="wp-caption-text">발표하는 모습</p></div>
<p>그리고 역시 블로거분들의 날카로운 질문들이 이어졌다. 같이 발표한 준성님의 유연한 대답과 달리 답변이 많이 꼬였던 것 같다. 특히 블로거뉴스는 &#8216;열려있다&#8217;라고 하면서 &#8216;열려있다&#8217;에 대한 정의를 내 자신의 틀에 맞추려고 하는 잘못이 있음을 깨닫게 되서 좋았다.</p>
<div id="attachment_220" class="wp-caption alignnone" style="width: 310px"><a href="http://fantazic.com/wp-content/uploads/2009/03/dsc_0740.jpg"><img src="http://fantazic.com/wp-content/uploads/2009/03/dsc_0740-300x199.jpg" alt="질문에 답변 중" title="질문에 답변 중" width="300" height="199" class="size-medium wp-image-220" /></a><p class="wp-caption-text">질문에 답변 중</p></div>
<p>7년째 개발을 하고 있는데 지금까지의 경험을 바탕으로 블로거뉴스를 통해 세상에 좀 더 가치있는 것을 만들어 내고 싶다. 많은 사람들이 관심을 가지고 있고 영향력을 갖고 있는 블로거뉴스가 &#8216;다음 뷰&#8217;로 변화하는 중심에서 내가 할 수 있는 것들, 우리가 할 수 있는 것들에 집중해서 최선을 다 할 것이다. <img src='http://fantazic.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/-cWJPxCy9TA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/217/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/217</feedburner:origLink></item>
		<item>
		<title>줄어든 블로깅… 마이크로 블로그가 필요하다?</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/3fURXIVQ_9s/214</link>
		<comments>http://fantazic.com/archives/214#comments</comments>
		<pubDate>Fri, 20 Feb 2009 07:18:51 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[Software &amp; Developer]]></category>

		<category><![CDATA[Lucene]]></category>

		<category><![CDATA[블로거뉴스]]></category>

		<category><![CDATA[블로그]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=214</guid>
		<description><![CDATA[좀처럼 블로그에 글을 작성하지 않고 있다. 그렇다고 글을 전혀 쓰지 않는 것도 아니다. 회사에서 담당하고 있는 블로거뉴스 관련한 글은 개발자 블로그에 글을 올리고 있고, 새로운 것을 공부하거나 개발 관련 정보를 조사하면 사내 개발자 위키에 정리해서 올린다. 그리고 가끔 떠오르는 생각들은 Yammer에 올려서 관심 있는 사람들과 의견을 나눈다. (Yammer는 메일 주소 기반으로 조직내의 짧고 빠른 의사소통을 [...]]]></description>
			<content:encoded><![CDATA[<p>좀처럼 블로그에 글을 작성하지 않고 있다. 그렇다고 글을 전혀 쓰지 않는 것도 아니다. 회사에서 담당하고 있는 블로거뉴스 관련한 글은 <a href="http://hallasan.tistory.com/">개발자 블로그</a>에 글을 올리고 있고, 새로운 것을 공부하거나 개발 관련 정보를 조사하면 사내 개발자 위키에 정리해서 올린다. 그리고 가끔 떠오르는 생각들은 <a href="https://www.yammer.com/home">Yammer</a>에 올려서 관심 있는 사람들과 의견을 나눈다. (Yammer는 메일 주소 기반으로 조직내의 짧고 빠른 의사소통을 가능하게 해주는 도구입니다.)</p>
<p>결국 정작 내 블로그에는 쓸 글이 없어지는 상황이 반복되고 있다. 그래서 짧게 글을 남길 수 있는 <a href="http://me2day.net/">Me2Day</a>에 사람들이 끌리는 것일까? WEB2.0의 열기는 식고 있는데 그 결과로 우리에게 남은 것은 무엇일까? 많은 사람들이 자신의 생각과 이야기를 웹에 담아 놓고 있다. 웹을 통한 집단 지성의 발휘가 가능할까? 웹을 통한 정보의 확산과 민주주의의 실현이 도래할까? 아직은 모든 것이 불확실하다.</p>
<p>어찌 되었건, 우선은 블로거뉴스를 통해 의미 있는 서비스를 만들어 보고 싶다. RDB 기반에서 검색 엔진 기반으로 전체 구조를 변경하고, 협업 필터링과 클러스터링을 활용해서 지금 구조에서는 불가능 했던 정보 조직화 및 전달이 가능하도록 하고 싶다. <a href="http://www.lucene.kr/">Lucene</a>도 다시 공부하고 <a href="http://lucene.apache.org/mahout/taste.html">협업 필터링 엔진</a>도 살펴봐야 한다. 녹슨 머리에 기름칠을 할 때인가 보다.</p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/3fURXIVQ_9s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/214/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/214</feedburner:origLink></item>
		<item>
		<title>2009년에는 어떤 모습으로 변할까?</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/q4HbqMcFkGU/212</link>
		<comments>http://fantazic.com/archives/212#comments</comments>
		<pubDate>Wed, 31 Dec 2008 04:53:56 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[Software &amp; Developer]]></category>

		<category><![CDATA[2008]]></category>

		<category><![CDATA[2009]]></category>

		<category><![CDATA[프로그래머]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=212</guid>
		<description><![CDATA[한해 한해 비슷한 듯 하면서도 매해 새로운 배움과 변화가 있었는데, 2008년은 개발자로서 NHN에서 미들웨어 개발에 집중할 수 있었고 Daum으로 이직하면서 다시 서비스 개발을 하게된 의미 있는 한해였다.
그렇다면 2009년에는 나는 또 어떤 모습으로 변하게 될까?
연말에 휴가를 보내는 중 아내가 나에게 물어보았다. &#8220;왜 개발을 해?&#8221;
토비님의 &#8216;진정한 프로의 모습&#8216;도 떠올랐고, &#8216;배움과 성장을 함께 하고 싶다&#8217;는 생각도 들었다. 난 [...]]]></description>
			<content:encoded><![CDATA[<p>한해 한해 비슷한 듯 하면서도 매해 새로운 배움과 변화가 있었는데, 2008년은 개발자로서 NHN에서 미들웨어 개발에 집중할 수 있었고 Daum으로 이직하면서 다시 서비스 개발을 하게된 의미 있는 한해였다.</p>
<p>그렇다면 2009년에는 나는 또 어떤 모습으로 변하게 될까?</p>
<p>연말에 휴가를 보내는 중 아내가 나에게 물어보았다. <strong>&#8220;왜 개발을 해?&#8221;</strong><br />
토비님의 &#8216;<a href="http://toby.epril.com/?p=538">진정한 프로의 모습</a>&#8216;도 떠올랐고, &#8216;배움과 성장을 함께 하고 싶다&#8217;는 생각도 들었다. 난 왜 프로그래머의 삶을 살고 있을까? 정말 중요한 가치를 만들어내고는 있는 것일까?</p>
<p>내년에는 &#8216;<a href="http://bloggernews.media.daum.net">블로거뉴스</a>&#8216;에 모든 고민과 능력을 집중시키는 한 해가 될 것 같다. 하나의 서비스를 통해 사람들의 소통을 확대시키고 지식을 나누고 서로 공감할 수 있게 할 수 있다면 내가 개발하는 것들이 의미있는 가치를 만들어내는 것이라 믿는다.</p>
<p>그래서 최근에는 개발보다는 사회 또는 웹에 관한 책을 많이 읽고 있다. 대부분 정독을 하기 보다는 전체적은 의미만 파악하고 있는데 나름 생각을 정리하는데 도움이 되고 있는 것 같다. 그리고 이런 생각들을 기술적으로 풀어낼 수 있는 고민들이 뒤따라야 할 것이다.</p>
<p>2009년은 지금까지 고민하고 익혀온 것들을 실험하는 한해가 되지 않을까? 빠르게 적용하고, 이를 통해 배우고, 다시 발전시키는 방식으로 서비스를 만들어가고 싶다. 같이 고민하고, 의견을 듣고, 최선의 결정을 내리고 싶다. 모든 사람들의 능력이 같이 성장할 수 있는 한해가 되고 싶다.</p>
<img src="http://feeds.feedburner.com/~r/fantazic/~4/q4HbqMcFkGU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/212/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/212</feedburner:origLink></item>
		<item>
		<title>눈꽃이 만발한 한라산</title>
		<link>http://feedproxy.google.com/~r/fantazic/~3/0KkwSMEsQHs/186</link>
		<comments>http://fantazic.com/archives/186#comments</comments>
		<pubDate>Sat, 27 Dec 2008 13:55:48 +0000</pubDate>
		<dc:creator>따지크</dc:creator>
		
		<category><![CDATA[시골생황]]></category>

		<category><![CDATA[겨울]]></category>

		<category><![CDATA[눈꽃]]></category>

		<category><![CDATA[사진]]></category>

		<category><![CDATA[한라산]]></category>

		<guid isPermaLink="false">http://fantazic.com/?p=186</guid>
		<description><![CDATA[지난 주 휴가 때는 날씨가 흐려서 멀리 나가지 못했다. 오늘은 모처럼 날씨도 좋고 해서 제주 올레 7-1 코스 개장에 참가하려고 했는데, 아침에 시간을 맞추지 못해서 한라산 등반으로 계획을 급변경했다.
겨울산은 10년전쯤 설악산 대청봉에 오르고 처음인 것 같다. 정인이는 운동 부족으로 많이 힘들어하긴 했지만 역시 중반 이후의 멋진 풍경에 크게 만족해 했고 눈꽃이 만반할 한라산과 파란 하늘, [...]]]></description>
			<content:encoded><![CDATA[<p>지난 주 휴가 때는 날씨가 흐려서 멀리 나가지 못했다. 오늘은 모처럼 날씨도 좋고 해서 <a href="http://jejuolle.org/">제주 올레</a> 7-1 코스 개장에 참가하려고 했는데, 아침에 시간을 맞추지 못해서 한라산 등반으로 계획을 급변경했다.</p>
<p>겨울산은 10년전쯤 설악산 대청봉에 오르고 처음인 것 같다. 정인이는 운동 부족으로 많이 힘들어하긴 했지만 역시 중반 이후의 멋진 풍경에 크게 만족해 했고 눈꽃이 만반할 한라산과 파란 하늘, 그리고 제주도를 둘러싼 바다의 모습까지 어느것 하나 부족하지 않았다.</p>
<p>컴팩트 카메라로 사진을 찍었는데, <a href="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=2593800">최근에 읽고 있는 책</a>을 보면서도 그랬지만 이제는 괜찮은 사진기를 하나 사고 싶어진다.</p>

<a href='http://fantazic.com/archives/186/halla_4951' title='halla_4951'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4951-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4954' title='halla_4954'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4954-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4957' title='halla_4957'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4957-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4958' title='halla_4958'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4958-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4964' title='halla_4964'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4964-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4966' title='halla_4966'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4966-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4968' title='halla_4968'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4968-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4969' title='halla_4969'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4969-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4970' title='halla_4970'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4970-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4973' title='halla_4973'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4973-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4974' title='halla_4974'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4974-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4978' title='halla_4978'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4978-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4979' title='halla_4979'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4979-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4988' title='halla_4988'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4988-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4992' title='halla_4992'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4992-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4993' title='halla_4993'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4993-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4996' title='halla_4996'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4996-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_5000' title='halla_5000'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_5000-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_5004' title='halla_5004'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_5004-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_5005' title='halla_5005'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_5005-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_5006' title='halla_5006'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_5006-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_5012' title='halla_5012'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_5012-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href='http://fantazic.com/archives/186/halla_4965' title='halla_4965'><img src="http://fantazic.com/wp-content/uploads/2008/12/halla_4965-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a>

<img src="http://feeds.feedburner.com/~r/fantazic/~4/0KkwSMEsQHs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fantazic.com/archives/186/feed</wfw:commentRss>
		<feedburner:origLink>http://fantazic.com/archives/186</feedburner:origLink></item>
	</channel>
</rss>
