Tuesday, June 30, 2009

[정보공유]「log4sql」의 소개

[정보공유]

[산소]로부터의 정보공유입니다.
java의 DAO계층에서 Statement로 쿼리를 부르는 경우, 정확히 어떤 쿼리가 전송되는지 로그를 남기도록 driver를 proxying하는 driver, 「log4sql」의 소개입니다.

http://log4sql.sourceforge.net/index_kr.html

한글, 일어의 페이지가 있습니다.(만, 일어페이지는 좀 깨져있군요)

비슷한 것으로 p6spy가 있습니다. p6spy가 더 많은 기능을 탑재하고 있다고 생각합니다만, 라이브러리 평가페이지 jars.developer.com에서 Top 25% Rated의 평가를 받고 있네요.
살펴볼만한 가치가 있다고 생각합니다.

이상.

Sunday, June 28, 2009

best practice of designing DAO

best practice of designing DAO

지금까지의 경험을 정리하는 것입니다만, DAO의 구축에 대해 한 번 알고 있는 모든 것을 동원해 "어떻게 하는 것이 좋은 지"에대해 한 번 생각해 보고자 합니다.
Database를 이용하는 우선 설계의 방식에는 여러가지가 존재할 수 있습니다. 각각 모두, 요구되는 '기록과 열람'이라는 내용은 만족합니다. 그러나 어떤 것이 왜 좋은지 알 지 못한다면 곤란합니다.

우선은 기본적인 Data의 설계는 각 프로젝트별로 맡기고, 여기에서는 공통적으로 다루어야 할 issue에 대해서만 촛점을 둡니다만, DB의 모델링에 대해서는 다양한 시스템에 대한 설계의 경험을 쌓아야 합니다.

각 프로젝트별로 필요한 필드의 추출, 추출방식은 도메인 모델을 기준으로 하던지, use case를 기준으로 해도 문제가 되지 않습니다. 또한 generalizing과 degeneralizing도 어느쪽에 비중을 더 크게 두더라도 틀린 것은 아닙니다. 오히려 어느쪽에 비중을 더 두었는 지를 보고, 어떤 기능이 들어가는지 기획을 짐작할 수 있습니다.
리소스에 여유가 있다면, Fetch용 Database와 DML용 Database를 따로 두는 것도 가능합니다. 이런 경우의 Database의 설계는 일반적인 경우와 많이 다른데, 일반적인 경우만 다루어본 사람이 이러한 구조를 알지 못한 채, 이런 ERD를 만나면, "DB를 잘 알지 못하는 사람이 작성했나보군"하고 생각할 지도 모릅니다.

공통적으로 다루어야할 Database의 설계에 대한 Issue로 여기고 있는 것은 다음과 같습니다. 안전한 Data의 취급이 무시되어야 하는 시스템은 없을 것입니다.
다음에 적는 것들은 없어도 기록의 출입을 구성하기에는 문제가 없습니다만, 고려해 보아야 할 내용들입니다.

1) Optimistic Lock
2) Trigger를 이용한 Update Delete시의 Transaction Table에의 기록.
3) Procedure를 이용한 DML(plus DML query의 실행제한)

Optimistic Lock은 시스템의 구성에 따라 꼭 필요하기도 하고, 없어도 상관없는 경우가 있습니다. Transaction의 기Term이 긴 시스템이라면 반드시 필요합니다. 구현은 프로시저를 사용하지 않고 코드에서 구현한다면, 상당한 작업량이 될 수 있습니다. 만일 프로시저를 사용할 수 없다라면, OR-Map의 도입도 고려해 보는 것도 좋다라고 생각합니다.

Trigger를 이용한 Transaction을 Table에 기록하는 것은 고객의 동작을 기록해 놓는 것으로 , 안전성의 의미가 큽니다.

Procedure를 이용한 DML은 parameter check도 코드에서 하는 것이 아니라 procedure에서 하겠다는 얘기입니다. Data기록의 로직은 Database의 Procedure에 두겠다는 것은 한 가지 언어 이외에도 복수의 언어로 구성된 시스템에서 동일한 기록의 동작을 보장합니다.

이것은 DB에 매우 큰 로드를 걸지 않는 한, 매우 바람직합니다라고 생각됩니다만, 실제로 많이 사용되는 경우는 보기 어려웠습니다. 특히 Procedure를 사용하지 않고, Application서버가 여러대로 분산되어 있을 경우 부하를 DB보다는 Application서버에 두려 하는 경우, 또 OR-Mapper를 더 선호해서 이를 통한 DML 작업을 하는 경우가 이유로 많이 제시되곤 했습니다.
그러나 잘 생각해보면, Hibernate등의 OR-Mapper를 사용한다고 하더라도 Select에 대한 작업은 Cache Provider등을 사용해 이득을 볼 수 있지만, Insert Update Delete에 대한 작업이 그리 많이 이득을 볼 수 있는 시스템이라고 확실히 얘기할 수 있는 시스템은 많지 않은 것 같습니다.
Hibernate등을 선호하는 케이스라면, 시스템이 허용하는 한, 사용해도 좋다고 생각합니다.
이런 경우라면 insert update delete 명령어를 금지하면 안되겠지만, DBA계정이 아닌, Application이 사용하는 계정이라면 금지를 생각해보는 것도 가능할 지 모릅니다.(실제 그렇게 운영해 본 적은 없습니다만...)

아아.. 오늘은 이만 해야겠습니다.
이 문서는 완전한 것이 아니므로 추가될 것입니다.

Saturday, June 20, 2009

Today, I kicked a small project off for me.

오늘 부터 작은 실험을 시작하려고 합니다.
어떤 실험인가 하면, 가끔 적는 이 블로그에, 한글은 물론, 일본어와 영어로 적어보려고 합니다.

제가 적는 블로그는 회사의 업무시간 가운데에 적는 것이 많습니다.(그래서 매우 단편적이면서, 깊지 않은 내용들이 많습니다.)
그렇기 때문에 처음에는 하나의 언어로만 적어두었다가 나중에 나머지 언어의 내용을 추가해 적는 경우도 있을 것입니다.

이상한 문장도 많이 쓰고, 뜻이 잘 못 전달 되는 경우도 있을 것입니다.
하지만 몇 년 꾸준히 계속하면 큰 공부가 될 것으로 기대합니다.

방문해 주시는 분께는 한가지 부탁으로, 잘 못된 문장을 지적해 주시면 제게는 큰 공부가 될 것입니다.
아무쪼록 잘 부탁드립니다.

====

今日から自分のためにひとつの小さい実験を始めようと思います。
どんな実験なのかというと、たまに書くこのブログに、ハングルは勿論、日本語と英語も一緒に書いて見ようと思います。
私の書くブログは会社の業務時間の中に書くことが多いです。(それで非常に断片的だし、深くない内容が多いです。)
そうだから初めには一つの言語でだけ書き留めてから後で残り言語の内容を追加して書く場合もあるでしょう。

変な文章もたくさん書いてしまい、意味がよく伝えられない場合もあるでしょう。
しかし何年弛まず続けば大きい勉強になることで期待します。

訪問していただいた方にはひとつお願いがありまして、間違った文章を指摘していただければ、私には大きい勉強になると信じています。
なにとぞよろしくお願いいたします。

====

Today, I kicked a small project off for me.
to say what it is, it is writing my blog posts with Hangul (of course!), japanese and english at once.

I usually write my posts in working time( that's why they are piecemeal and outline-like)
so I might publish posts written with one language and add other languages later.

sentences will be wrong and ridiculous.
but I will hang on it for years and it will be a good study

to visitors, please leave your comment for me.
your little advice for my wrong english is great help
thank you.

Friday, June 19, 2009

groovy cgi

groovy파일을 cgi로 이용해 사용하는 장난(?)을 하다가, parameter를 받는 작업을 하던중, 제대로 처리하게 하지 못해서 애를 좀 먹었습니다.
한글이나 일본어가 깨지는 현상때문이었는데요. 파일도 utf-8(without BOM), 그리고 groovy.exe의 실행옵션에서 도움말에 있는 --encoding UTF-8 이나 -c UTF-8을 아무리 주어도 제대로 표시되지 않았습니다. 아파치의 설정이 잘못된 것인지도 보고, 옵션이 먹지 않는지 레지스트리의 .groovy파일 실행할 때 디폴트 옵션을 줘보기도 했습니다만, 해결은 다른 방법으로 되었습니다. 옵션에 -Dfile.encoding=UTF-8 을 주고 실행하는 것이었습니다.

아마도, 스펙대로라면 -Dfile.encoding=UTF-8 이 없어도 잘 표시되어야 할 것 같은데...., 잘 되지 않았습니다.


#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe -Dfile.encoding=UTF-8
//C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe -c utf-8 -D file.encoding=UTF-8

import java.net.URLDecoder;
def decoder = URLDecoder;

print "Content-type: text/html\n\n"
print "<html><head><meta content='text/html; charset=utf-8' http-equiv='Content-Type'/></head><body>"
def name='World'; println "Hello $name!"

/* == to show all env variables
def env = System.getenv()
for(k in env){
println(k)
} */

def __form = [:]
def arrykeyvalue
def strQueryString = System.getenv()['QUERY_STRING']
if (strQueryString != null) {
def arryForm = strQueryString.split('&')
arryForm.each {
arrykeyvalue = it.split('=')
__form.put(arrykeyvalue[0], arrykeyvalue[1])
}
}

__form.each {
print (it.key + ' = ' + it.value+ '<br>')
}

__form.each {
print (it.key + ' = ' + decoder.decode(it.value, "UTF8") + '<br>')
}

print "日本語 <br> "
print "한국어 <br> "
print "</body></html>"



html 태그가 있어 본문에 에러가 있다고 하니 일본어의 전각 괄호로 바꾸었습니다.
그리고 아래가 실행 내용입니다.




Wednesday, June 17, 2009

[정보공유] 윈도우즈환경에서 groovy로 cgi하기

최근에는 perl 프로젝트를 하고 있는 영향도 있지만, cgi의 재발견이랄까 재미를 느끼고 있는 것은 사실입니다.
도메인이니, 모델이니, DAO니 BL이니 하는 라이브러리를 만들고 난 뒤 여러 복잡한 프레임웍의 설정과 웹어플리케이션의 설정을 하고 나서야 페이지 하나를 볼 수 있는 엔터프라이즈급의 개발은 분명 가벼운 마음으로 할 수 있는 것은 아닙니다.
작은 프로그래밍을 가벼운 마음으로 해보기 부담스러운 것은 grails, gsp도 마찬가지에요. 그런의미에서 cgi는 상대적으로 부담이 적기 때문에 작은 프로그래밍을 해보기에는 적합합니다.

groovy로 cgi를 하는 방법은 전에도 한번 시도해보았었습니다만, 윈도우즈환경은 리눅스와 달리 groovy.bat 파일로 실행되는 결과를 output으로 보내기에는 적합하지 못했습니다. 왜냐하면 아파치 프로세스가 cgi용 파일을 만나면 그 파일을 열어 Shebang #! 을 보고 어떤 명령을 실행해서 값을 구할 지 처리하는 과정에서, cgi용 파일에 groovy.bat로 해석하라고 전달하게 되는데 ,
아파치 process가 groovy.bat test.goory 명령을 실행하면, 그 프로세스에 output이 return되어 지는 것이 아니라, bat파일을 해석하기 위해 %comspec%가 실행된 다음 그 프로세스안에서 다시 jre를 실행한 뒤 결과값인 output이 나오기 때문에, bat를 실행시킨 process에서는 output을 구할 수 없기 때문입니다.
Shebang을 사용하지 않고 AddHandler나 Registry에 Associated Application을 설정한 경우에도 잘 되지 못했습니다.
이야기가 길어졌습니다만, 결론은, 윈도우에서 제대로 groovy파일을 cgi로 사용하지 못했다. 라는 이야기 입니다.

반면 아마도 리눅스 환경에서는 -시도해 본 일은 없습니다만 - 아파치프로세스가 groovy 쉘 스크립트를 실행하여 output을 얻는 것은 특별히 문제가 되지 않을 것 같다는 생각이고, 또 그렇게 했다는 블로그를 본 적도 있습니다.

=============

그런데 최근 잠깐 살펴보니 Native Launcher 라는 것이 등장해 있었군요.
http://groovy.codehaus.org/Native+Launcher
groovy.exe를 바로 다운받을 수 있는 링크도 있습니다.

왜 groovy.exe를 사용해야 하는지 적어놓은 부분도 있습니다만, 여기에는 cgi 이야기는 없군요. (원래 할 수 있는 것을 제가 못해낸 건지도 모르겠습니다.)
어쨌든, 이 groovy.exe로 cgi설정을 해보았습니다. (apache와 groovy까지는 설치되어 있다고 가정합니다.)

groovy.bat 파일을 groovy.bat.old 로 옮기고,

httpd.conf 안에 LoadModule이 끝나는 곳에 다음 한 줄 추가

setEnv GROOVY_HOME c:\Progra~1\Java\groovy-1.6.0
(또는 PassEnv GROOVY_HOME 해도 되나요. 확인해 보지 않았습니다.)

그리고 .groovy파일 더블클릭하면 groovy.exe파일이 실행되도록 설정해 놓고. AddHandler는 특별히 추가하지 않았습니다.

그리고 다음과 같이 test.groovy cgi를 하나 만들고

#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe
print "Content-type: text/html\n\n"
def name='World'; println "Hello $name!"

실행해 보았습니다.


-_-)=b

HtmlBuilder까지 사용하는 것은 무난할 것 같습니다.

#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe
print "Content-type: text/html\n\n"

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.html(){
head(){
title("Groov'n with Builders"){}
}
body(){
p("""Welcome to Builders 101. As you can see
this Groovlet is fairly simple.""")
}
}
println writer.toString()


하지만 servlet이 아니므로 request나 response등의 객체는 사용할 수 없습니다. (사용하게 하려면 매번 web.xml을 읽어 ServletConfig를 new 하고, Servlet을 new하고... 해야 할 것 같습니다.)

앞으로 CGI방식으로 %ENV%에서 값을 받아오는 Method나 Class를 만들어보죠.

Monday, June 15, 2009

「폰더씨의 실천하는 하루」에서

「폰더씨의 실천하는 하루」에서

함께 어울리는 사람을 선택하는 과정에서 한 가지 염두에 둘 게 있다.
친구를 선택할 때에는 신중해야 한다는 것이다. 나는 사람들에게 종종 "당신이 생각하는 진정한 친구는 어떤 사람입니까?"라고 묻는다. 80퍼센트 이상의 사람이 "진정한 친구란 있는 그대로의 내 모습을 받아들이는 사람"이라고 답한다. 세상에! 이건 정말 위험한 발상이다. 동네 페스트푸드 식당의 아르바이트생은 있는 그대로의 내 모습을 받아들인다. 왜냐면 그는 나와 아무 관련이 없기 때문이다.
진정한 친구란 '나를 보다 높은 수준으로 끌어올려 주는 사람'이다. 그가 내 곁에 있음으로써 내가 보다 나은 사람이 될 수 있게 하는 존재다.

「폰더씨의 실천하는 하루」 Chapter "동료의 힘", 한글판 78페이지.

그리고 나는 여기에 매우 동의합니다.

김동현.

Sunday, June 14, 2009

[세상에 이런일이] 회의중 만들어낸 명령어

[세상에 이런일이]

금요일 회의중에 시스템 엔지니어 郷古상이 잠깐 기다려 보라며, 만들어낸 리눅스 명령행

for aln in `vzctl exec 200 "chkconfig --list | cut -f1 | sort | uniq | grep -v ":" | egrep -v '^$'"`;do vzctl exec 200 service $aln status > /dev/null 2>&1;ret=$? ;echo "$aln: $ret";done

한줄 명령이며 이 안에 외부 커맨드는 7개가 들어가 있습니다.
그리고 완벽하게 잘 실행되었습니다.

그는 이런 명령어를 그자리에서 만들어서 보여준, 내가 만난 두 번째 일본인입니다.

-_-)=b