Whiteship's Note

'2009/11'에 해당되는 글 34건

  1. 2009.11.30 [봄싹] 점진적인 개발
  2. 2009.11.30 [웹 사이트 속도 향상 베스트 프랙티스 8] 자바스크립트와 CSS 외부화하기 (3)
  3. 2009.11.29 오늘은 내가 요리사 - 탕수육 (6)
  4. 2009.11.27 봄싹 사이트 1.0 M1 오픈 임박!! (4)
  5. 2009.11.26 그래!! 이정도는 해야 앵무새라고 할 수 있지! (2)
  6. 2009.11.25 [웹 사이트 속도 향상 베스트 프랙티스 7] CSS expression 사용하지 않기
  7. 2009.11.24 애노테이션 VS XML, 상속, static method call, ... (4)
  8. 2009.11.24 [웹 사이트 속도 향상 베스트 프랙티스 6] 스크립트를 바닦에 두기
  9. 2009.11.24 봄싹을 알리러 갑니다. (6)
  10. 2009.11.23 한 순간... (8)
  11. 2009.11.23 [웹 사이트 속도 향상 베스트 프랙티스 5] 스타일시트를 HEAD에 넣기 (2)
  12. 2009.11.21 봄싹에서 자바 코드가 차지하는 비중은 1/3 (2)
  13. 2009.11.21 [피아노] 아내와 연탄곡 - 말할 수 없는 비밀 (2)
  14. 2009.11.19 [웹 사이트 속도 향상 베스트 프랙티스 4] 컴포넌트 압축하기(Gzip Components)
  15. 2009.11.18 [IntelliJ] 블럭 포매팅 귿!
  16. 2009.11.18 [웹 사이트 속도 향상 베스트 프랙티스 3] Expires 또는 Cache-Control 헤더 추가하기
  17. 2009.11.17 [웹 사이트 속도 향상 베스트 프랙티스 2] CDN(Content Delivery Network) 사용하기 (2)
  18. 2009.11.17 인터넷의 의미 - 친절
  19. 2009.11.17 I have been serializing my packages.
  20. 2009.11.16 [스프링 3.0] RC2 릴리즈~
  21. 2009.11.16 [웹 사이트 속도 향상 베스트 프랙티스 1] HTTP 요청 최소화 하기 (4)
  22. 2009.11.16 [봄싹 축하] 제 9회 다음 DevDay 대상! (다음 에디터 플러긴 WordAssist) (6)
  23. 2009.11.13 [WCG 2009] 요즘 하고 있었군요. (4)
  24. 2009.11.12 [코딩] 데이터를 요청하지 말고 작업을 요청하라. (2)
  25. 2009.11.10 [IntelliJ] 9.0 베타 공개 (4)
  26. 2009.11.10 [하이버네이트] @BatchSize로 쿼리 갯수 대폭 줄이기
  27. 2009.11.09 [봄싹] 커뮤니티 지원 요청 실패 (12)
  28. 2009.11.05 [Atlassian Connector] IntelliJ 플러그인
  29. 2009.11.05 [GreenHopper] Atlassian JIRA의 애자일 개발 플러그인 (4)
  30. 2009.11.04 [메이븐] 하이버네이트 플러그인

[봄싹] 점진적인 개발

모하니?/Coding : 2009.11.30 13:52


봄싹에서 Agile 방법론을 공부한 적은 없지만, 자연스럽게 그와 비슷한 형태의 개발이 진행되는걸 보는 재미가 쏠쏠 합니다. 그 중 하나로 점진적인 개발을 들 수 있습니다. 다들 바쁜 생업을 하는 중에 짬을 내서 개발을 하는 중인데다가, 배포 주기를 될 수 있으면 짧게 가져가고 있기 때문에 '설계'에 많은 시간을 투자할 여유도 없거니와 전부 개발자이자 고객이기 때문에 '요구사항 정리'나 '문서화'에 시간을 들여야 할 이유가 별로 없습니다. 그 대신 구글 그룹스에서 활발한 토론을 통해서 필요한 기능에 대한 대충의 윤곽을 잡은 다음, 해당 기능을 만들고 싶은 개발자가 스스로 원하는데로 만듭니다. 그 뒤에 누군가 피드백을 주면, 다시 개발자는 그 피드백을 고객의 요구사항이라고 생각하고 되도록이면 반영해줍니다. 또는 피드백을 준 개발자가 직접 해당 기능을 손보기도 합니다. 그 과정 중에 자연스럽게 점진적인 개발을 실천하게 됩니다.

봄싹 사이트 0.9

지금 보시는 화면은 봄싹 0.9 버전의 메인 화면입니다. 전부가 정적인 구성요소로 HTML 파일로 만든것과 다를바 없는 JSP 파일이었습니다.

현재는 아래처럼 바뀌었습니다.

1. 제일 처음 디자인이 바뀌었습니다. 페이지는 여전히 HTML과 다를바 없었습니다. 낙서장, 공지사항, 스터디, 위키, 세미나, 커버플로우, 협찬 로고 등 아무것도 동적인 데이터는 없었습니다.

2. 그러다 낙서장 기능이 추가됩니다. 낙서장도 처음에는 정적인 디자인부터 시작했고, 동적으로 li를 추가하게 바뀌었습니다. 여기서 사용한 기술이 조금 재미있습니다. 페이지 릴로딩을 하지 않고 Ajax로 요청을 주기적으로 보내서 HTML을 업데이트 하는 방식입니다. 사용자는 가만히 첫 페이지를 열어두면 다른 사람들의 낙서가 업데이트 되는걸 볼 수 있습니다.

3. 다음은 공지 사항이 추가되었습니다. 그러면서 낙서장은 계속해서 디자인이 바뀌고 스크롤 방식이 바뀌어 나갑니다. 공지는 제이쿼리 플러긴을 이용해서 이쁜 팝업을 띄우게 되었고, 공지 목록이 길어지면 스크롤링을 하기 위해 처음부터 모든 데이터를 가져오지 않고 애초에 Ajax로 필요한 만큼의 데이터만 가져옵니다. 하지만 아직 스크롤링이 완전히 구현되어 있지는 않습니다. 아직도 개발 중인거죠.

4. 다음은 스터디 목록을 추가했습니다. 이 부부는 Ajax를 사용하지 않았었습니다. 처음에는 스터디 목록만 전부 읽어와서 랜더링 될 때 보여주고 끝이었습니다. 그러나 조금 뒤에 바뀌게 됩니다. 공간이 넉넉하고 스터디에 속한 모임을 주로 참조하는 관계로, 모임 목록까지 보여줘야할 필요가 생겼습니다. 하지만 사용자가 어떤 스터디의 모임목록을 원하는지도 모르면서 모든 모임 목록을 가져오고 싶지는 않았습니다. 그래서 Ajax를 적용했고, 하이버네이트 쿼리 캐쉬를 적용해서, 일단 한번 DB에서 가져온 모임 목록은 일정 시간동안 다시 쿼리를 날리지 않고도 보여주게 했습니다. Ajax 요청 캐시까지 적용하면 더욱 좋겠지만, 그건 아직 다음 과제로 남겨뒀습니다.

5. 마지막은 위키였습니다. 위키 목록은 스터디 목록을 뿌리는 것과 동일했습니다. 다만 위키 제목이 길어질 여지가 있어서 길이를 어느정도로 짜른다음 ...을 붙이도록 개선했습니다.

이와 같이 메인 페이지를 구성하는 것들 중에 어느 하나도 한 번에 개발이 끝난것이 없으며, 지금도 사실 완전히 끝났다고 볼 수 없는 기능들이 많습니다. 메인 페이지의 구성요소 하나 하나도 자세히 히스트로리를 들여다보면 점진적으로 개발되고 있는 모습을 볼 수 있습니다. 낙서장이 대표적입니다. 처음에는 정적인 리스트였다가. Ajax로 추가할 수 있게 바뀌고, 스크롤바를 추가했다가, 지금은 마우스 드래그로 바뀌었고, 무한 드래그에서 끝이 막히는 드래그로 바뀌었습니다. 공지, 스터디, 위키도 그렇게 매우 자연스럽게 진화를 거듭하고 있습니다.

조금씩.. 쓸 수 있는 상태를 유지하면서.. 발전하기.

바로 이런게 점진적인 개발 아닐까요?

참조: 롤러스케이트 구현
신고
top


[웹 사이트 속도 향상 베스트 프랙티스 8] 자바스크립트와 CSS 외부화하기

모하니?/Coding : 2009.11.30 12:38


http://developer.yahoo.com/performance/rules.html#external

Make JavaScript and CSS External

tag: javascript, css

많은 성능관련 규칙들이 어떻게 관리중인 컴포넌트들을 외부화 하는지를 다루고 있다. 하지만, 그 전에 보다 기본적인 질문에대해 생각해봐야 한다. 자바스크립트와 CSS는 외부 파일에 들어있어야 하는가 아니면 페이지 자체에 포함되어 있어야 하는가?

실제로는 외부 파일을 사용함으로써, 브라우저가 자바스크립트와 CSS를 캐시하여 페이지 로딩 속도를 향상시킬 수 있다. HTML 문서에 들어있는 자바스크립트와 CSS는 매번 HTML 문서를 요청받을 때마다 다운로드 된다. 이렇게 하면 필요한 HTTP 요청을 줄일 수 있기는 하지만, HTML 문서 크기를 증가시킨다. 반면에, 만약 자바스크립트와 CSS를 외부 파일로 두고 브라우저가 캐시할 수 있게 하면 HTML 문서 사이즈도 줄이고 HTTP 요청 수의 증가도 없다.

그렇다면, 중요한 것은 요청되는 HTML 문서의 양에 비해 상대적으로 캐시 해야하는 자바스크립트와 CSS 컴포넌트 빈도이다. 수치화하기 어려울 수 있지만, 이 요소는 다양한 척도를 통해 계산할 수 있다. 만약 사이트의 사용자가 세션 당 여러 페이지를 요청하고 페이지의 대부분에서 동일한 스크립트와 스타일시트를 재사용한다면, 외부 파일 캐시를 통해 얻을 수 있는 잠재적인 장점이 더 크다.

대부분의 웹 사이트는 이러한 척도 중간에 놓여있다. 그러한 사이트에서 최선은 선택은 보통 자바스크립트와 CSS를 외부 파일로 배포하는 것이다. 페이지에 포함시키는 것이 더 좋을 수 있는 예외로 야후의 첫 페이지와 마이 야후 같은 홈 페이지가 있다. 홈 페이지는 세션당 페이지 뷰가 거의 없다. (대부분 하나다) 따라서 자바스크립트와 CSS를 페이지에 포함시키는 것이 최종 사용자 응답 시간을 줄일 수 있다.

여러 페이지 뷰로 연결되는 첫 페이지의 경우, 외부 파일을 통해 캐시 장점을 이용하는 것 말고도 HTTP 요청을 줄이는 기술들이 있다. 그런 기술 중 하나가 자바스크립트와 CSS를 첫 페이지에 두지만, 외부 파일을 페이지 로딩이 끝난 뒤에 동적으로 다운로드하는 것이다. 그 다음 연쇄적으로 호출되는 페이지들은 이미 브라우저의 캐시된 외부 파일을 참조할 것이다.

신고
top


오늘은 내가 요리사 - 탕수육



주말은 원래 집청소와 요리가 제 담당입니다. 주중에는 아내가 다 해주지만, 주말 만큼은 제가 하려고 노력중이죠. 하지만;; 생각만큼 많이 도와주진 못합니다.ㅋ 할 줄 아는게 있어야죠.ㅋㅋㅋ 결혼하기 전에 라면 끓여먹을줄만 알았지 전기밥솥으로 밥하는 방법도 몰랐으니 말이죠.

어찌됐든, 오늘의 요리는 탕수육이었습니다. 물론 아내가 메인 주방장이었고 저는 보조였습니다.



만들면서는 이 손 많이 가는걸.. 그냥 사먹고 말지.. 괜히 탕수육을 먹는다고 그랬나.. 했었는데, 직접 만든 탕수육을 먹어보니 감회가 새롭더군요. 캬캬캬 재밌고 맛있었습니다.

신고
top

TAG 탕수육

봄싹 사이트 1.0 M1 오픈 임박!!

모하니?/Coding : 2009.11.27 08:35


현재 봄싹 사이트(0.9)에서 보다 더 스터디 관리 기능을 보강했으며, 위키 디자인을 개선하여 편의성을 높였습니다. 트위터와 이메링을 비롯한 다양한 알림 서비스도 이용하실 수 있습니다. 특히 구글 토크를 사용하시는 분들은 스터디나 모임이 있을 때 메시지를 받을 실 수 있는것은 기본이고, 채팅창에서 study? meeting? 으로 현재 진행중인 스터디와 모임 정보를 확인하실 수도 있습니다. 홈 페이지에는 낙서장과 공지 사항을 추가했으며 스터디-모임 목록, 위키 목록으로 바로 이동할 수 도 있습니다. 또한 컨텐츠 작업으로, 스프링 3.0 레퍼런스 번역이 활발히 진행중입니다. 위키를 더 개선하고나면 저도 본격적으로 봄싹 컨텐츠 만들기 작업에 돌입할 생각입니다. 스프링소스 블로그 번역, 각종 웹 아티클 번역 자료를 봄싹 위키에 정리할 겁니다. 아무래도 제 블로그 보다는 위키가 찾아보기 편하니까요. (블로그에도 올리긴 할 겁니다.ㅋ)

내용적인 면이나 기능적인 면을 떠나서 이번 배포의 가장 큰 주안점은 바로 디자인입니다.

불과 두 달 사이에 획기적으로 달라진 봄싹 1.0 M1은 내일 낮에 오픈합니다.


Develop with passion! Evolve with SpringSprout!!




신고
top

TAG 1.0 M1, 봄싹

그래!! 이정도는 해야 앵무새라고 할 수 있지!

모하니?/Watching : 2009.11.26 11:48




앵무새인지.. 뭔지... 녹음기가 달려있나?ㅋㅋ



신고
top

TAG 앵무새

[웹 사이트 속도 향상 베스트 프랙티스 7] CSS expression 사용하지 않기

모하니?/Coding : 2009.11.25 10:56


http://developer.yahoo.com/performance/rules.html#css_expressions

Avoid CSS Expressions

tag: css

CSS expression은 CSS 속성을 동적으로 설정할 수 있는 강력(하면서도 위험)한 방법이다. IE 버전5 부터 지원되기 시작했다. 예를 들어, CSS 표현식을 사용하여 배경 색을 매 시마다 다르게 설정할 수 있다.

      background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

여기 보시다시피, expression 메서드는 자바스크립트 표현식을 받아들인다. CSS 속성은 자바스크립트 표현식을 계산한 결과로 설정된다.. expression 메서드는 다른 브라우저에서는 무시된다. 따라서 여러 브라우저에 걸쳐 일관적인 경험을 제공하고자 할 때 IE에 속성을 설정하는 방법으로 유용하다.

expression의 문제는 사람들이 예상한 것보다 훨씬 빈번히 계산된다는 것이다. 페이지가 렌더링 되고 크기 조절이 될 때에만 계산되는 것이 아니라, 페이지를 스크롤 하거나 사용자가 페이지 위에서 마우스를 움직일떄에도 계산한다. CSS 표현식에 카운터를 추가하여 CSS expression을 얼마나 계산했는지 추적할 수 있다. 마우스를 페이지에서 움직이면 거의 10,000 번이 넘게 계산을 수행한다.

CSS expression 계산 횟수를 줄일 수 있는 방법은 딱 한 번만 expression를 수행하도록 하는 것이다. 처음 expressio을 계산할때 stype 속성을 CSS expression 대신 명시적인 값으로 교체한다. 만약 스타일 속성이 반드시 페이지가 살아있는 동안 동적으로 바뀌어야 한다면, CSS Css expression 대신 이벤트 핸들러를 사용하는것도 하나의 대안이다. 만약 반드시 Css expression을 사용해야 한다면,수 천번 계산될 거라는 것과 그로인해 페이지 성능에 영향을줄수 있다는 것을 염두하라.
신고
top


애노테이션 VS XML, 상속, static method call, ...

모하니?/Coding : 2009.11.24 14:20


봄싹 그룹스에서 애노테이션과 XML에 대한 논쟁이 어제 낮부터 오늘 낮까지 24시간 동안 불이 날 정도로 이어지고 있습니다. 하지만 애노테이션은 XML 하고만 비교당할 수 있는게 아닙니다.

스프링 테스트는 어떤가요?  이건 "애노테이션 VS 상속"의 문제입니다.
스프링 컨트롤러는 어떤가요? 그것도 "애노테이션 VS 상속"의 문제입니다.
Mockito의 @Mock은 어떤가요? 이건 "애노테이션 VS static method call"의 문제 아닐까요?

이렇게 여러 기술(?)과 비교 당할 수 밖에 없는 애노테이션이 저는 불쌍하고 애처롭습니다.

애노테이션아. 넌 왜 그렇게 유능해서(?).. 여러명한테 동시에 비교를 당해야 하는거니? 불쌍해서 봐줄수가 없구나.. 흑흑..
신고
top


[웹 사이트 속도 향상 베스트 프랙티스 6] 스크립트를 바닦에 두기

모하니?/Coding : 2009.11.24 11:24


http://developer.yahoo.com/performance/rules.html#js_bottom

Put Scripts at the Bottom

tag: javascript

스크립트가 야기할 수 있는 문제는 병렬적인 다운로드를 막는다는 것이다. HTTP/1.1 표준은 브라우저가 호스트 이름당 두 개 이상의 컴포넌트를 병렬적으로 다운로지 하지 않도록 제안하고 있다. 만약 이미지를 여러 호스트 이름에서 제공한다면, 병렬적으로 두 개 이상의 다운로드가 발생하게 할 수 있다. 하지만, 어떤 스크립트를 하나 다운로드 할 때, 브라우저는 심지어 다른 호스트 이름에 있는 것이라 하더라도, 어떠한 다운로드도 시작하지 않는다.

어떤 상황에서는 스크립트를 바닦으로 옮기는 것이 쉽지 않을 수 있다. 예를들어, 만약 스크립트가 document를 사용하여 페이지의 내용 중 일부를 채우는 것이라면 페이지 하단으로 옮길 수가 없다. 또한 스코프와 관련된 이슈도 있을 수 있다. 대부분의 경우, 이런 상황에 대한 차선책이 있기 마련이다.

보통 자주 사용하는 차선책으로 지연된(deffered) 스크립트를 사용하는 방법이 있다. DEFER 속성은 해당 스크립트가 document.write를 가지고 있지 않다고 알려주며 브라우저가 계속해서 랜더링을 할 수 있는 단서가 된다. 불행히도, 파이어폭스는 DEFER 속성을 지원하지 않는다. IE에서는 스크립트를 지연시킬 수 있지만, 원하는 만큼은 아니다. 만약 스크립트를 지연시킬 수 있다면, 페이지의 바닦으로 옮길 수도 있을 것이다. 그렇게 하면 웹 페이지의 로딩 속도가 더 빨라질 것이다.
신고
top


봄싹을 알리러 갑니다.

모하니?/Planning : 2009.11.24 10:47


http://www.ibm.com//developerworks/kr/event/seminar/dwlive_1205/index.html
http://www-903.ibm.com/kr/event/seminar/seminar.jsp?seminar_id=440

오늘 저녁에는 KSUG 모임에 가서 봄싹 사이트 개발과 관련된 내용을 요약해서 발표합니다.

다음주 토요일에는 한국 IBM "웹 개발 다반사"라는 행사에서 봄싹에 대해 발표 하고자 제의한 상태입니다. 페차쿠차 형식으로 발표를 진행한다는데.. 뭔지 다들 아시겠죠? 한 장을 20초 내로 넘기면서 총 20장 정도로 약 6.7분간 발표하는 독특한 발표형식입니다.

내년 봄에 날이 좀 따뜻해지기 시작하면, 봄싹 세미나를 할 계획을 가지고 있는데, 위 두 가지 활동은 그 사전 준비에 해당하는 활동이라고 볼 수 있습니다. 이밖에도 각종 행사에 봄싹 타이틀을 걸고 출전할 계획도 가지고 있습니다.

봄싹은 더이상 스터디만 하는 커뮤니티가 아닙니다. 온라인에서 잡담만 나누는 커뮤니티도 아닙니다. 이미 올해 중반부터는 스터디 보다는 개발에 더 많은 비중을 두고 있고, 현재도 스터디 계획 못지 않게 여러가지 개발 계획을 가지고 있습니다. 개발 뿐인가요? 번역과 베타리딩에 대한 계획도 있고, 각종 대회 출전 계획도 있습니다. 모임의 형태가 완전히 달라졌습니다. 한마디로 진보했습니다. 그리고 그 속에서 팀원들의 스킬도 여러 면에서 향상되고 있습니다. 단순히 개발 스킬 뿐 아니라, 커뮤니테이션 스킬과 발표 스킬 그리고 운영 능력을 키우고 있습니다.

이러한 발전을 이룩한건 전부 다 봄싹 팀원들이 각자 열심히 노력한 결과이자 과정이며, 그것들을 여과나 포장없이 순수하게 공유하고 받아들이는 팀원들의 마인드가 중요했다고 생각합니다. 이러한 발전 속에서 기술적으로 혹은 문화적으로 어떠한 일들이 있었는지 내용들을 정리해서 발표해야겠습니다.

궁금하신 분들은 KSUG는 장소가 협소하니, 다음주 "웹 개발 다반사 행사"에서 뵐 수 있을지도;

ps: 아직 발표 주제로 채택도 안 됐는데 이렇게 써도 될라나.ㅋㅋㅋ
신고

'모하니? > Planning' 카테고리의 다른 글

백기선's 2010 Weekly Report - 2/23  (2) 2010.02.23
목표 실천은 진행 중  (12) 2010.02.17
백기선 2010 목표  (12) 2010.02.15
봄싹 Career Path  (6) 2009.12.17
이번주 토요일 IBM dW "웹 개발 다반사"  (2) 2009.12.03
봄싹을 알리러 갑니다.  (6) 2009.11.24
[Atlassian] 이직 계획  (2) 2009.11.02
[ToDo] 20091016  (0) 2009.10.16
[ToDo] 오늘 할 일 - 할일(예상 소요 시간)(실제 소요 시간)  (4) 2009.10.15
2009년 마무리로 할 일  (4) 2009.10.08
9월에 할 일 정리  (10) 2009.08.31
top


한 순간...

모하니?/Thinking : 2009.11.23 23:43


독방에 틀어박혀 미친듯이 개발만 하고 싶다는 생각이 들어서 와이프에게 물어봤다.

"자기야.. 나 휴가내고, 한 달만 미친듯이 개발만 하면 안 될까?"

참.. 내가 생각해도 어이가 없는 질문이기는 하다. 아내가 현명하게 대처해줘서 고마울 뿐이다.

한순간 가장으로써의 의무를 망각했던 것 같다. 하고 싶은 걸 하는 건 좋치만 중용은 지켜야겠다.

일단은 번역이 우선인가... 에흄;
신고
top


[웹 사이트 속도 향상 베스트 프랙티스 5] 스타일시트를 HEAD에 넣기

모하니?/Coding : 2009.11.23 15:53


http://developer.yahoo.com/performance/rules.html#css_top

Put Stylesheets at the Top

tag: css

야후에서 성능 조사를 하는 동안, 스타일 시트를 문서의 HEAD로 옮기는 것이 페이지 로딩을 더 빠르게 해준다는 것을 발견했다. 스타일 시트를 HEAD에 놓음으로써, 페이지 랜더링이 더 빨라지기 때문이다.

성능을 고려하는 화면 엔지니어는 페이지 로딩이 빨라지길 원한다. 즉, 브라우저가 어떤 내용이던지 가능한 빨리 보여주길 원한다. 이것은 느린 인터넷 연결을 사용하는 사용자와 보여줄 내용이 많은 페이지에서 특히 중요하다. 진행 상태 표시와 같은 시각적인 피드백을 주는 것의 중요함에 대해서는 설문조사가 잘 되어 있고 잘 문서화 되어 있다. 우리의 경우 HTML 페이지가 곧 진행 상태 표시기이다! 브라우저는 페이지 헤더를 빠르게 로딩할 때 네비게이션 바, 화면 윗 부분의 로고 등 모든 시각적인 피드백을 해당 페이지를 기다리는 사용자에게 제공한다. 그런식으로 전반적인 사용자 경험을 향상시킬 수 있다.

스타일시트를 문서의 바닥으로 넣는 것의 문제는 IE를 포함한 대부분의 브라우저에서 빠른 랜더링을 방해하기 때문이다. 이들 브라우저는 문서의 스타일이 바뀌면 페이지의 요소들을 다시 그려야 하는 것을 방지하기 위해 랜더링을 막아둔다. 그 때 사용자는 하얀색의 빈 화면에 머물러 있게 된다.

HTML 표준은 분명히 스타일시트를 페이지의 HEAD에 포함시킬 것을 기술하고 있다. "[LINK]는 얼마나 많이 있던 문서의 HEAD 부분에만 있어야 한다." 그 어떠한 대안도 비어있는 하얀 화면이나 스타일이 없는 내용으로 채워진 플래시 등의 위험을 감당할 만한 가치가 없다. 최적의 해결책은 HTML 표준을 따라 스타일시트를 문서 HEAD 안에서 로딩하는 것이다.
신고
top


봄싹에서 자바 코드가 차지하는 비중은 1/3

모하니?/Thinking : 2009.11.21 14:05


현재 봄싹 소스 코드를 분석해본 결과, 절반에 가까운 코드가 화면 관련 코드입니다.

자바스크립트, CSS, JSP까지 치면, 절반이 넘고, 자바 코드는 1/3에 불과하군요.

화면 개발이 얼마나 중요하고 심오한가를 느낌으로만 짐작하고 있었는데, 이렇게 실체적인 데이터를 보니까 새록 새록 합니다.

화면 개발자들 멋지십니다.
신고
top


[피아노] 아내와 연탄곡 - 말할 수 없는 비밀






저희 부부는 이러고 놀아요.

제가 좀 많이 틀렸지만, 그나마 나은 걸로 골랐습니다. 캬캬캬
이제 스터디 가야겠군요.

신고
top


[웹 사이트 속도 향상 베스트 프랙티스 4] 컴포넌트 압축하기(Gzip Components)

모하니?/Coding : 2009.11.19 13:02


http://developer.yahoo.com/performance/rules.html#gzip

Gzip Components

tag: server

HTTP 요청과 응답을 네트워크로 전송하는데 걸리는 시간을 화면 개발자들과의 논의를 통해 극적으로 줄일 수 있다. 물론 최종 사용자의 인터넷 속도는 개발 팀과 관계없는 인터넷 서비스 제공처와 접근하려는 곳과의 거리에 따라 달라지기는 한다. 하지만 그 외밖에도 응답 시간에 영향을 주는 변수들이 있다. 압축을 기용하면 HTTP 응답의 크기를 줄여서 응답 시간을 빠르게 할 수 있다.

HTTP/1.1 부터, 웹 클라이언트는 HTTP 요청의 Accept-Encoding 헤더를 사용하여 압축 형태를 지원한다는 것을 알려줄 수 있게 되었다.

      Accept-Encoding: gzip, deflate

만약에 웹서버가 요청에 들어있는 이 헤더를 본다면, 응답을 클라이언트가 나열한 방법으로 압축할 수가 있다. 웹 서버는 웹 클라이언트에게 응답의 Content-Encoding 헤더를 사용하여 사용한 방법을 알려준다.

      Content-Encoding: gzip

Gzip은 근래 가장 유명하고 효율적인 압축 기술로, GNU 프로젝트에 의해 만들어졌으며 RFC 1952로 표준화 되었다. 다른 압축 기술중 여러분이 보고 싶어하는 것으로 deflate가 있지만 Gzip에 비해서 덜 효율적이며 덜 알려져있다.

Gzip 압축은 응답의 크기를 약 70% 가량 쥴여준다. 아마도 근래의 브라우저를 떠돌고 있는 인터넷 트래픽 중 90%는 gzip을 지원한다고 선언해 두었을 것이다. 만약 아파치를 사용하고 있다면, gzip 모듈 설정 방법은 버전에 따라 다르다. 아차피 1.3은 mod_gzip을 사용하고 아파치 2는 mod_deflate를 사용한다.

브라우저와 프록시를 사용할 때 브라우저가 예상한 것과 실제로 압축하여 받은 내용이 일치하지 않는 이슈가 있다. 다행히도, 구 버전 브라우저 사용이 점차 줄어듬에 따라 그런 이슈도 줄어들고 있다. 아파치 모듈은 Vary 응답 헤더를 사용하여 자동으로 적절한 타입을 찾도록 도와준다.

서버는 파일 타입에 따라 무엇을 gzip으로 압축할지 선택하지만, 실제로 무엇을 압축할지 결정한 것을 보면 매우 제한적이다. 대부분의 웹 사이트는 그들의 HTML 문서를 gzip으로 압축한다. 스크립트와 스타일시트도 압축할 만한 가치가 있는데 대부분의 사이트는 이것을 간과한다. 사실, 응답에 들어가는 모든 XML, JSON, 이미지, PDF 파일 등은 압축하지 말아야 한다. 이미 압축되어있는 형태기 때문이다. 그것들을 압축하는 것은 CPU를 낭비하는 것일 뿐 아니라 잠재적으로 파일 사이즈를 늘리는거나 마찬가지다.

Gzip으로 가능한 많은 타입을 압축하는 것은 페이지의 무게를 줄이고 사용자 경험을 가속화하는 쉬운 방법이다.


신고
top


[IntelliJ] 블럭 포매팅 귿!

Good Tools : 2009.11.18 17:38



마우스로 긁은 다음 포매팅 단축키를 먹이면 위와 같은 팝업이 뜹니다. 기본으로 블럭 포매팅이기 때문에 엔터를 치면 해당 부분만 포매팅이 되죠. 꺄오~ 좋아 좋아.

이클립스에서도 된다는군요. java, jsp, js, css 등에서도 잘 되는지 해보세요~

신고
top


[웹 사이트 속도 향상 베스트 프랙티스 3] Expires 또는 Cache-Control 헤더 추가하기

모하니?/Coding : 2009.11.18 16:34


http://developer.yahoo.com/performance/rules.html#expires

Add an Expires or a Cache-Control Header

tag: server

이 규칙에는 두 가지가 있다.

* 정적 컴포넌트인 경우: 아주 긴 시간으로 Expires 헤더를 설정하여 "Neber expire" 정책을 구현한다.
* 동적 컴포넌트인 경우: 적절한 Cache-Control 헤더를 사용하여 브라우저를 도와준다.

웹 페이지 디자인은 점점 더 풍부해지고 있다. 즉 보다 많은 스크립트, 스타일시트, 이미지, 플래시가 페이지에 들어간다는 것이다. 여러분 페이지를 처음 방문하는 사용자는 아마도 몇 개의 HTTP 요청을 보내야 할 것이다. 하지만 Expires 헤더를 사용하여 그런 컴포넌트들을 캐시가 가능하도록 설정할 수 있다. 이렇게 하면 연속하여 페이지를 참조할 때 불필요한 HTTP 요청을 줄일 수 있다. Expires 헤더는 대부분 이미지에 자주 사용하지만, 스크립트, 스타일시트, 플래시 컴포넌트를 포함한 모든 컴포넌트에도 활용할 수 있다.

브라우저(와 프록시)는 캐시를 사용하여 HTTP 요청과 사이즈를 줄이고, 웹 페이지 로딩 속도를 높인다. 웹 서버는 Expires 헤더를 HTTP 응답에 사용하여 클라이언트가 얼마나 오래 컴포넌트를 캐시할지 알려준다. 다음은 아주 오래동안 캐시를 보관하도록 설정한 Expires 헤더이다. 브라우저에게 이 응답은 2010년 4월 15일까지 변하지 않을꺼라고 알려준다.

      Expires: Thu, 15 Apr 2010 20:00:00 GMT

만약 여러분의 서버가 아파치라면, ExpiresDefault 지시자를 사용하여 현재 시간 기준으로 상대적인 만료 날자를 설정하라. 다음 예제는 만료 날짜를 요청을 받은 시점 부터 10년 뒤로 설정하는 ExpiresDefault 지시어다.

      ExpiresDefault "access plus 10 years"

명심해야 할 것이 있다. 만약 아주 오래 살도록 Expried 헤더를 사용한 경우에는 컴포넌트를 변경할 때 마다 반드시 컴포넌트의 파일이름을 변경해 주어야 한다. 야후에서는 이런 작업을 빌드 과정 중 하나로 만들어 사용한다. 컴포넌트의 파일 이름에 버전 넘버를 명시해주는 것이다. 예를 들어 yahoo_2.0.6.js 처럼.

아주 오래 캐시를 유지하도록 설정한 Expires 헤더는 이미 여러분의 사이트를 방문했던 사용자가 보는 페이지에만 적용된다. 사이트를 처음 방문하는 사용자의 HTTP 요청이거나 브라우저의 캐시가 비어있는 경우에는 아무런 영향이 없다. 따라서 이런 성능 개선의 효과는 사용자가 어느정도 '준비된 캐시'를 가지고 페이지를 얼마나 자주 방문하느냐에 달려있다. ('준비된 캐시'에는 페이지의 모든 컴포넌트를 이미 가지고 있다.) 우리는 야후에서 이것을 측정했고 그 결과 준비된 캐시를 가지고 방문하는 페이지 뷰의 수가 75~85%에 달한다는 것을 발견했다. 아주 왜 캐시를 유지하는 Expires 헤더를 사용함으로써, 브라우저가 캐시할 컴포넌트 수를 늘리고 연쇄적으로 페이지를 볼 때 사용자 인터넷 연결에 한 바이트로 보내지 않을 수 있다.

참조: http://www.mnot.net/cache_docs/
신고
top


[웹 사이트 속도 향상 베스트 프랙티스 2] CDN(Content Delivery Network) 사용하기

모하니?/Coding : 2009.11.17 21:39


http://developer.yahoo.com/performance/rules.html#cdn

Use a Content Delivery Network

tag: server

여러분 웹 서버에 대한 사용자 접근은 응답 시간에 영향을 준다. 컨텐츠를 여러개로 분산되어 있는 서버에 배포한다면 사용자 시점에서 페이지 로딩을 빠르게 할 수 있다. 하지만 무엇부터 시작해야 할까?

지리학적으로 분산되어 있는 컨텐트(geographically dispersed content)를 구현할 때 제일 먼저 할 것은, 여러분의 웹 애플리케이션을 분산 아키텍처로 다시 설계하는 짓을 하지 않는 것이다. 애플리케이션에따라, 아키텍처의 변경은 여러 곳에 위치한 서버를 넘나드는 '세션 상태 동기'와 '데이터베이스 트랜잭션 복사' 작업의 압박을 받을 수 있다. 사용자와 컨텐츠 사이의 거리를 좁히려는 시도는 그러한 애플리케이션 아키텍처 변경 단계로 말미암아 연기 되거나 그 단계를 못 벗어날지도 모른다.

기억할 것은 80-90%의 최종 사용자 응답 시간은 페이지의 컴포넌트들(이미지, 스타일시트, 스크립트, 플래시 등)을 다운로드 하는데 소비 된다는 것이다. 바로 이것이 성능에 있어서 황금 법칙이다. 여러분 애플리케이션 아키텍처를 다시 설계하는 어려운 작업부터 시작하지 말고, 정적인 컨텐츠들을 분리하는 것부터 먼저 하는 것이 더 좋다. 응답 시간을 크게 줄여줄 뿐 아니라, 고마운 CDN 덕분에 그 작업도 쉽다.

CDN은 보다 효율적으로 사용자에게 컨텐츠를 제공하기 위해 여러 곳으로 분산되어 있는 웹 서버 집합이다. 특정 사용자에게 컨텐츠를 제공할 서버는 기본적으로 네트워크 접근성 측정을 기반으로 선택된다. 예를 들어, 가장 낮은 네트워크 홉(hop)을 가지고 있거나 가장 빠른 응답 시간을 가지고 있는 것이 선택된다.

몇몇 대규모 인터넷 회사들은 자신들의 CDN을 가지고 있지만, Akamai Technologies, Mirror Image Internet, Limeight Networks 같은 CDN 서비스 제공자를 사용하는 것이 비용적으로 효율적이다. 신생 회사나 개인적인 웹 사이트의 경우 CDN 서비스 비용이 비쌀수도 있지만, 여러분의 대상 고객이 점점 증가하고 점점 글로벌화 됨에 따라, 첫 응답 시간을 높이기 위해 CDN이 필요해질 것이다. 야후에서 정적인 컨텐츠를 웹 서버에서 CDN으로 옮김으로써 사용자 응답 시간을 20% 이상 향상 시켰다. CDN으로 바꾸는데 필요한 것은 여러분의 웹 사이트 속도를 극적으로 향상시키는것에 비해 상대적으로 간단하게 코드를 변경하기만 하면 된다.
신고
top


인터넷의 의미 - 친절

모하니?/Watching : 2009.11.17 21:11




악플러보다 친플러들이 많다는 거...
신고
top

TAG 인터넷

I have been serializing my packages.



좀전부터 계속 하고 있었고 지금 이 순간에도 하는 중이었기 때문에 현재 완료 진행형을 사용했습니다. 내일 회사가 합정에서 압구정으로 이사를 가기 때문에 짐정리를 하고 있었는데, 이전에도 한 번 비유한 적이 있지만 '이사'라는 건 꼭 자바의 '직렬화'랑 비슷합니다.

짐을 죄다 이동할 수 있는 형태로 쌓아두고, 이동한 다음, 다시 다 풀어제끼니 말이죠.
그 모양새가 딱 직렬화, 역질렬화랑 매치되지 않나요.
아님 말구요.ㅋ

부디 내일 이사가 일찍 끝나길...

ps: 대체 이 회사에 들어와서 이사를 몇 번이나 하는거야. T.T 벌써 세 번째. 아흑..


신고
top


[스프링 3.0] RC2 릴리즈~

Spring/3.0 : 2009.11.16 22:54


요즘 스프링에 관심이 슬슬 가시기 시작하네요. 벌써 3일이나 지나서야 RC2로 버전을 올리다니.. 예전 같았으면 공개되자마자 버전을 올렸을텐데 말이죠. 하긴.. 뭐 3일 정도 늦었지만, 그래도 봄싹은 아마도 한국에서 가장 빨리 스프링 최신 버전을 적용한 프로젝트가 될 것 같습니다. 후훗

중요 변경 사항을 살펴보겠습니다.

* updated to final versions of JSR-330 "javax.inject" and JSR-303 "javax.validation" APIs
* full compliance with the JSR-330 TCK (i.e. full compliance with the final specification)
* support for Hibernate Validator 4.0 GA (as the JSR-303 reference implementation)
* added support for load-time weaving in JBoss 5.x
* added support for recent EHCache 1.6 configuration properties to EHCacheFactoryBean
* added AnnotatedBeanDefinitionReader helper for programmatic registration of annotated classes
* added AnnotationConfig(Web)ApplicationContext for convenient registration/scanning of classes
* added GenericXmlApplicationContext with flexible configuration options for its XML support
* AbstractApplicationContext can also start up in case of system properties access failure
* internal MergedBeanDefinitionPostProcessors apply after all other post-processors
* inner beans detected as ApplicationListeners as well (only supported for inner singletons)
* child bean definition's scope attribute can be inherited from parent bean definition now
* introduced SmartLifecycle interface with auto-startup and shutdown order support
* introduced LifecycleProcessor delegate, customizable through "lifecycleProcessor" bean
* MessageListenerContainers and Quartz SchedulerFactoryBean start up on refresh instead of init
* added initialize-database tag to jdbc namespace for populating external data sources with data
* PathMatchingResourcePatternResolver leniently ignores non-existing root directories
* DefaultConversionService understands "on"/"off", "yes"/"no", "1"/"0" as boolean values
* CustomEditorConfigurer supports PropertyEditor instances again (with deprecation warning)
* revised MethodParameter's annotation accessor methods
* ClassUtils is now parameterized with Class<?> and Class<T> where appropriate
* DataBinder now accepts var-args to set allowed, disallowed, and required fields
* DataBinder auto-grows nested paths on traversal (avoiding NullValueInNestedPathException)
* fixed enum binding regression with WebRequestDataBinder (as used by @MVC data binding now)
* fixed FieldError to expose rejected input value as String value instead of as array
* JSR-303 Validator will only register validation failures if no binding failure happened
* ContentNegotiatingViewResolver works with ignoreAcceptHeader and defaultContentType as well
* added Spring MVC namespace, with convenient mvc:annotation-driven configuration element
* default number and datetime formatters configured when using the Spring MVC namespace
* full support for datetime formatting using the Joda Time library (automatically enabled)
* added convenient @NumberFormat and @DateTimeFormat annotations for declarative formatting
* implicit T.valueOf(S) and constructor T(S) lookup if no explicit S->T converter matches
* AbstractExcelView is compatible with Apache POI 3.0 as well as 3.5 now
* TilesConfigurer only sets up EL support if JSP 2.1 is present (for JSP 2.0 compatibility)
* re-introduced Struts 1.x support ("org.springframework.web.struts") in deprecated form
* deprecated scheduling support for JDK 1.3 Timer ("org.springframework.scheduling.timer")
* deprecated remoting support for JAX-RPC (in favor of JAX-WS)


신고
top


[웹 사이트 속도 향상 베스트 프랙티스 1] HTTP 요청 최소화 하기

모하니?/Coding : 2009.11.16 18:46


참조: http://developer.yahoo.com/performance/rules.html#num_http

HTTP 요청 최소화하기(Minimize HTTP Requests)

tag: content

사용자 응답 시간 중 80%가 브라우저 단(front-end)에서 소요된다. 이 시간 중 대부분이 페이지의 모든 컴포넌트들(이미지, 스타일시트, 스크립트, 플래시 등)을 다운로드 하는데 소요된다. 컴포넌트의 갯수를 줄이면 페이지를 랜더링하는데 필요한 HTTP 요청의 수도 줄어들게 된다. 바로 이것이 페이지 로딩 속도를 높이는 핵심이다.

화면에 있는 컴포넌트의 수를 줄이는 한가지 방법은 페이지의 디자인을 단순하게 만드는 것이다. 하지만 꽤 복잡한 컨텐츠로 구성되어 있는 페이지를 만들 때도 빠른 응답 속도를 보장할 수 있는 방법은 없을까? 이제부터 풍요롭게 디자인된 페이지를 지원하면서도 HTTP 요청을 줄이는 기술을 몇 가지 살펴보자.

묶음 파일(Combined files)이란 모든 스크립트를 하나의 스크립트로 묶고, 그와 비슷하게 모든 CSS를 하나의 스타일시트로 묶어서 HTTP 요청을 요청을 줄이는 방법이다. 묶음 파일은 페이지 마다 필요한 스크립트와 스타일시트가 다를 때 좀 더 도전적인 과제가 될 수 있지만, 이러한 것을 배포 절차 중 하나로 만든다면 응답 시간을 줄일 수 있다.

CSS Sprites는 이미지 요청 수를 줄일 때 선호하는 방법이다. 배경 이미지들을 하나의 단일 이미지로 묶고 background-image와 background-position 속성을 사용해서 이미지의 일부를 보여주는 것이다.

Image map은 여러 개의 이미지 파일을 하나의 이미지로 만든다. 전체 사이즈는 거의 같겠지만, HTTP 요청의 수가 줄어들어 페이지 로딩 속도가 빨라진다. 이미지 맵은 네비게이션 바와 같이 연속적으로 나타나는 이미지 일 때 적합하다. 이미지 맵의 좌표를 정의하는 것은 매우 지루하고 오류를 범하기 쉬울 것이다. 이미지 맵을 사용하여 네비게이션을 하는 것 또한 적용하기 쉽지 않다. 따라서 권장하는 방법은 아니다.

인라인 이미지(inline image)는 data: URL 스키마를 사용하여 이미지 데이타를 실제 페이지에 첨부한다. 이렇게 하면 HTML 문서의 크기가 늘어난다. 인라인 이미지를 (캐싱을 사용하는) 스타일시트에 넣는 방법으로 HTTP 요청을 줄이고 문서 크기가 늘어나는 것을 방지할 수 있다. 하지만 아직 인라인 이미지를 모든 주요 브라우저에서 지원하고 있지는 않다.

페이지에 필요한 HTTP 요청을 줄이는 것부터가 시작이다. 특히 이것은 첫 방문자를 위한 성능 향상에서 가장 중요한 가이드라인이다.  Tenni Theurer의 블로그 글 Browser Cache Usage - Exposed!에 따르면, 매일 여러분의 사이트 방문자 중 40~60%는 캐시가 비어있는 상태에서 찾아온다. 처음 방문하는 유저를 위해 페이지 로딩 속도를 높이는 것은 더 나은 사용자 경험에 있어서 핵심이다.
신고
top


[봄싹 축하] 제 9회 다음 DevDay 대상! (다음 에디터 플러긴 WordAssist)

모하니?/Thinking : 2009.11.16 11:38


다음 에디터 plugin 계발 계획? 생각? 삽질?
다음 에디터 PulgIn !! wordAssist

봄싹에서 같이 스터디 중인 분들 중에 총 세 분이 출전해서, 그 중 두 분이 한 팀으로 만든 다음 에디터 플러그인이 대상을 탔습니다. 상품으로 닌텐도 Wii를 받아왔고, 그것을 현금화 한 금액 중에서 참가 경비를 제외한 거의 전액을 봄싹에 기부했습니다.

저역시 지난번 제주도에서 열린 다음 DebDay에 참석하고 왔었지만, 사실 상에는 관심이 없었고 와이프랑 제주도로 놀러 갈 생각이었기 때문에 이런 성과는 기대도 하지 않았었는데, 이번에 참가한 팀은 아이디어도 멋졌고 그걸 매우 짧은 시간 안에 만들고 그것으로 상까지 받아왔다는 소식에 정말 놀라지 않을 수 없었습니다. 게다가 전액 기부라니 너무 완벽해서 샘이 날 정도입니다.

이번에 입상한 에디터 플러그인은 봄싹에서 별도의 프로젝트로 계속 관리를 해 나갈 것이며, 다음 에디터 및 WordAssist는 봄싹 사이트에 최대한 빨리 적용할 겁니다. (아마도 위키쪽에..)

흑.. 너무 멋지자나. ㅠ.ㅠ
신고
top


[WCG 2009] 요즘 하고 있었군요.

모하니?/Watching : 2009.11.13 17:14


http://www.wcg.com/6th/tv/live_streaming_WCG2009.asp?ch=1&lang=5&ca=0&qu=on

라이브로 볼 수 있네요.

스타 안 본지 한참 됐는데 오랜 만이로군요.
이제동, 송병구, 김택용 파이팅~
신고
top

TAG wcg

[코딩] 데이터를 요청하지 말고 작업을 요청하라.

모하니?/Coding : 2009.11.12 18:45


어떤 컨트롤러 안에 다음과 같은 코드가 있습니다.

    @RequestMapping("/study/{studyId}/meeting/delete/{meetingId}")
    public String deleteMeeting(@PathVariable int studyId,
            @PathVariable int meetingId) {
        Meeting meeting = meetingService.getById(meetingId);
        meetingService.deleteMeeting(meeting);
        return redirectStudyView(studyId);
    }

안그래도 컨트롤러 코드를 보면 항상 무언가 미적지근한 것이 있었는데, 그 원인을 이제야 알겠네요. 이 글의 제목에 적혀있는 객체지향 원리(?)를 생각해볼때 위와 같은 코드의 문제점은 무엇일까요?

이상하죠.. meeting을 model에 주어 담을 것도 아닌데, 뭐하러 가져와서 다시 service쪽에 넘겨주는 걸까요. 저런 식으로 코딩한 부분이 한 두군데가 아닙니다. 죄다 고쳐야겠어요. 크헉!!!!;;;;;




신고
top

TAG 코딩

[IntelliJ] 9.0 베타 공개

Good Tools : 2009.11.10 23:53


http://www.jetbrains.com/idea/nextversion/index.html?9b_eu

유겐같이 지적이며 총명한 개발자들이 쓴다는 인텔리J 9.0 베타가 나왔군요.
벌써부터 지원하는 기능이 빵빵하네요.


업그레이드나 하구 자야지~


신고
top


[하이버네이트] @BatchSize로 쿼리 갯수 대폭 줄이기

모하니?/Coding : 2009.11.10 01:04


참조:
- http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html
- http://docs.jboss.org/hibernate/stable/annotations/api/org/hibernate/annotations/BatchSize.html

스터디의 회원은 각각 Collection<Study, Integer> 타입의 목록을 가지고 있습니다. 스터디당 참여율이나 신뢰도가 들어있는 콜렉션입니다. 그리고 스터디를 보여줄 때 각 회원들의 참여율과 신뢰도를 보여주도록 되어 있는데, 문제는 쿼리입니다.

Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id=?
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id=?

이런 쿼리가 회원 수*2 만큼 생성됩니다. 한 회원당 attendanceRate와 trustRate를 가지고 있기 떄문이죠. 바로 이런 경우 @BatchSize를 사용하면 쿼리를 대폭 줄일 수 있습니다. 설정은 간단하죠;

    @CollectionOfElements(targetElement = Integer.class)
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
    @BatchSize(size=30)
    private Map<Study, Integer> studyAttendanceRates;

    @CollectionOfElements(targetElement = Integer.class)
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
    @BatchSize(size=30)
    private Map<Study, Integer> studyTrustRates;

설정을 한 뒤 쿼리 갯수는 대폭 줄어들게 됩니다. 물론 그만큼 빨라지죠.

Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select studytrust0_.Member_id as Member1_0_, studytrust0_.element as element0_, studytrust0_.mapkey_id as mapkey3_0_ from Member_studyTrustRates studytrust0_ where studytrust0_.Member_id in (?, ?)
Hibernate: select studyatten0_.Member_id as Member1_0_, studyatten0_.element as element0_, studyatten0_.mapkey_id as mapkey3_0_ from Member_studyAttendanceRates studyatten0_ where studyatten0_.Member_id in (?, ?)

신고
top


[봄싹] 커뮤니티 지원 요청 실패

모하니?/Thinking : 2009.11.09 21:33


D모 업체에 오픈 소스 커뮤니티 호스팅을 지원해주는 서비스가 있길래, 봄싹 커뮤니티를 지원해 주십사 요청을 했었지만, 실패했다. 제한된 리소스로 말미암아 좀 더 대중적으로 영향력 있고 관심가질 만한 커뮤니티를 지원해줘야하는데, 봄싹은 현재 부적절하다고 판단한 듯 하다.

그렇긴 하다. 현재 봄싹 스터디는 이제 막 1년을 넘긴 새싹과도 같은 커뮤니티이고, 그 특성상 유명세나 회원수 부풀리기에는 관심이 없는 커뮤니티이다. 현재로써는 스프링, 하이버네이트, 스프링 웹 플로우, 스프링 시큐리티, Maven, Nexus, Git, SVN, CI 및 개발 환경(Wiki, IntelliJ, Redmine, Github, Atlassian의 모든 제품) 등을 실험적으로 사이트 개발에 적용하고 그 소스 및 과정을 오픈하고 있다는 것 외에는 딱히 이렇다할 오픈 소스 제품이 없는 것도 사실이다.

하지만 미래를 볼 때, 봄싹 스터디는 충분히 지원을 받을 만한 가치가 있는 커뮤니티라고 생각한다. 개발자는 그 어느 직종 보다도 꾸준한 학습이 필요한 직종이 아닌가 생각한다. 그런면에서 봄싹은 1년이 넘도록 꾸준히 스프링을 중심으로 자바 개발에 관한 학습을 했으며, 지금 이 시간에도 계속해서 학습을 하고 있다. 물론 앞으로도 계속해서 학습을 해 나갈 것이다. 그리고 중요한 것은 그 학습한 내용들을 될수 있는한 모두 공개하고 있다는 것이다. 봄싹 스터디에 직접 참여하지 못하는 분들일지라도 온라인을 통해 충분히 학습 내용을 간접경험할 수 있다. 음성 녹화부터 최근에는 캠코더 촬영까지 갖은 방법을 동원하고 있다.

현재 봄싹 사이트는 내가 다니고 있는 회사 서버에 올려져 있다. 봄싹의 새 이슈 트래커(Jira), Nexus, 구 이슈 트래커(Redmine) 등은 봄싹 스터디 회원팀원 중 한명의 개인 컴퓨터를 개발 서버로 세팅해놓고 쓰고 있다. 램이 1G다. JIra가 먹는 메모리만 400M가까이 되서 최근에 자신이 쓰던 컴터의 2G 램을 떼어서 서버에 붙였다. 도메인은 위키북스의 Pro Spring 2.5 책을 베타리딩하고 받은 사례금으로 장만했다. 스터디 장소는 한빛교육센터의 도움으로 간간히 장소비 없이 스터디를 할 수 있게 되었다.

이런 환경에서도 봄싹은 매주 토요일 오전 10시 ~ 오후 1시 꾸준히 활동하고 있다. 매주다. 매주. 한 주는 스프링 스터디를 하고 한 주는 사이트 개발을 하고 있다. 주중에 일하고 주말 중 토요일을 하루 종일 스터디에 투자하는 회원팀원도 있다. 오프라인 모임만 매주 하는 것이지 사실 온라인에서는 매일 개발과 관련된 토론이 오고가며, 개인적으로 사이트 개발을 진행하거나 학습한 것을 공유하고 있다.

나는 절대로 한번도 그렇게 해달라고 요청한 적이 없다. 모두 스스로가 하고 싶어서 자발적으로 참여하는 것이고 그렇게 하지 못한다고 눈총을 주거나 면박을 주지도 않는다. 오히려 그렇게 열심히 학습하고 있는 개발자를 응원하고 그 회원팀원으로부터 자극을 받는 듯 하다. 나는 봄싹 스터디의 운영진 중 한 명으로써 그렇게 열심히 참여하는 사람들에게 좀 더 쾌적한 스터디 환경을 마련해주고 싶다. 그래서 항상 고민한다.

어떻게 하면 돈을 덜 들이고 스터디에 참여할 수 있을까? 어떻게 하면 조용하고 코딩하기 좋은 장소를 얻을 수 없을까? 발표자에게 어떤식으로 보상을 해줘야 할까? 발표자료는 어떻게 보관하고 공유할까? 어떤 형태로 발표를 기록해 주어야 할까? 어떻게 스터디 일정을 알리고 공유할까? 어떻게 하면 스터디 관리를 쉽게 할 수 있을까? 등등의 고민을 항상하고 있고, 그 해결책을 계속해서 구상하고 있다. 여태까지 모색한 방법 중 하나가 바로 봄싹 사이트 개발이고, 또 다른 방법 하나는 이번에 시도했던 커뮤니티 지원을 받는것이다. 그나마 다행으로 봄싹 사이트 개발은 어느 정도 효과를 보고 있는 것 같다. 하지만 그것으로는 부족하다.

봄싹은 분명히 보다 좋은 환경이 필요하다. 봄싹 스터디에 참여하는 개발자들이 편하게 스터디를 할 수 있는 공간이 필요하며, 편하게 필요한 애플리케이션을 돌려볼만한 웹 서버와 호스팅이 필요하다. 환경적인 기회를 강조한 "아웃라이어"라는 책을 봤다면 이해할 수 있을 것이다. 봄싹은 어떻게든 지금처럼 이어나갈 수 있을지도 모르겠다. 그러나 더 좋은 환경에서 자랄 수 있게 도와준다면 봄싹은 더 빨리 더 무성한 꽃을 피울 수 있을 것이다.

뭐.. 어쨋거나 하나가 실패했으니 다른 방법을 더 열심히 잘 준비해야겠다.

출처: http://noandnot.tistory.com/41

봄싹 파이팅!!!
신고
top


[Atlassian Connector] IntelliJ 플러그인

Good Tools : 2009.11.05 22:57


 아틀라시안 제품들과 IntelliJ 플러그인을 연동했는데... 이건 뭐.. 최강조합입니다. 마치 디아블로에서 큐브에 아이템 몇개 넣고 돌려서 좀 더 희귀한 아이템을 만들어 내듯이.. 지금 전 인텔리J와 아틀라시안 제품들을 조합해서 Agile 개발에 가장 적합한 개발 환경을 세팅했습니다.

인텔리J의 장점 중 하나를 꼽으라면 플러그인 설치가 편하고 안정적이라는 것을 꼽고 싶은데요. 안써본 분들에게 설명하자니 귀찮고, 써본분들에게는 딱히 설명드릴께 없기 때문에 패스하겠습니다.


저런식으로 설치한 아틀라시안 제품들과 연결을 해주고, 잘 쓰면 됩니다.


밤부 플러긴은 기본적으로 빌드가 성공했나 실패했나를 알려주는데, 맨 아래 녹색 모양의 조그만 아틀라시안 아니콘이 그 역할을 해줍니다.

그밖에 여러 기능들과 사용법은 아래 링크에 있습니다.

http://confluence.atlassian.com/display/IDEPLUGIN/Working+with+Bamboo+Builds+in+IDEA


지라 플러긴은 주로 이슈를 보고, 진행하거나, 멈추거나, 마무리 하거나, 새 이슈를 등록할 수 있습니다.

그밖에 여러 기능과 사용법은 아래 링크에 있습니다.

http://confluence.atlassian.com/display/IDEPLUGIN/Working+with+JIRA+Issues+in+IDEA

ps: 이클립스에서 IntelliJ로 갈아타길 정말 잘한것 같아요. 너무 안정적이에요. 인텔리J가 메모리 때문에 뻗는다 하더라도, 절대로 깨져버린 이클립스처럼 피곤하진 않습니다. 플러그인 설치도 간편하고 말이죠. 인텔리J 킹왕짱!!

내일은 Crucible과 FishEye도 설치하고 연동해야겠군요.
아.. 아틀라시안 제품 간에도 연동 시켜줘야겠네요.

신고
top


[GreenHopper] Atlassian JIRA의 애자일 개발 플러그인

Good Tools : 2009.11.05 08:57


http://www.atlassian.com/software/greenhopper/


스프링 이슈 트래커를 보다가 카드 모양으로 생긴 이슈 관리가 있길래 뭔가 봤더니, GreenHopper라는 플러그인이더군요. 완전히 새로운 UI로 이슈 관리를 할 수 있습니다. 드래그 앤 드랍으로 우선 순위를 변경한다던지, 카드 목록 화면에서 바로 바로 이슈를 수정한다던지 말이죠. 제가 궁금한건 기간과 난이도에 대한 추정을 하고, 그걸 통계내주는 기능이 있느냐인데.. 일단은 한번 설치해 봐야겠습니다.


신고
top


[메이븐] 하이버네이트 플러그인

Build/Maven : 2009.11.04 10:34


참조:
http://kwon37xi.springnote.com/pages/2275410
http://mojo.codehaus.org/maven-hibernate3/hibernate3-maven-plugin/componentproperties.html

1. 메이븐 pom.xml 에 플러그인 추가하기

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>hibernate3-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <componentProperties>
                        <drop>false</drop>
                        <create>true</create>
                        <format>true</format>
                        <export>false</export>
                        <jdk5>true</jdk5>
                        <outputfilename>schema.ddl</outputfilename>
                        <configurationfile>src/hibernate.cfg.xml</configurationfile>
                        <propertyfile>database.properties</propertyfile>
                    </componentProperties>
                    <components>
                        <component>
                            <name>hbm2ddl</name>
                            <implementation>annotationconfiguration</implementation>
                        </component>
                    </components>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>postgresql</groupId>
                        <artifactId>postgresql</artifactId>
                        <version>8.2-507.jdbc3</version>
                    </dependency>
                </dependencies>
            </plugin>

굵은 글씨 부분은 사용하시는 프로젝트에 맞게 변경해야 할 부분입니다.

일단, 구조를 보면 configuration에 크게 두가지가 들어있는데, 하나는 component들을 담고 있는 components이고, 다른 건 componentProperties입니다. 제가 사용하려는건 hbm2ddl이기 때문에 hbm2ddl 컴포넌트만 등록해 두었습니다. 그와 관련된 설정은 componentProperties여기에 들어있죠.

먼저, drop은 기존의 DB의 테이블 들을 깔끔하게 날려버릴 sql을 만들지 여부를 나타냅니다. 기본 값은 false기 때문에 위와 같은 설정에서는 생략해도 됩니다.

create는 뭔지 아시겠죠? 패스. 기본값은 true입니다.

format은 보기 좋은 형태로 SQL 출력 형태를 다듬어 줍니다. 기본 값은 false입니다.

export는 현재 DB에 적용을 할꺼냐는 건데.. 위험하기 때문에 일단은 false가 좋겠습니다. 그런데 기본값은 true입니다. 하지만, DB 마이그레이션 자동화가 되어있다면 true로 놓고 매번 DB 스키마를 새롭게 업데이트 한 다음 백업했던 데이터를 채워주면 되겠습니다.

jdk5는 역시 패스. 기본값은 false입니다.

outputfilename는 ddl을 출력할 파일 이름인데, 이 파일은 프로젝트/target/hibernate3/sql 밑에 생깁니다.

configurationfile는 하이버네이트 설정 파일 위치를 알려줍니다.

propertyfile는 하이버네이트가 DB에 접근할 때 필요한 프로퍼티를 가지고 있는 파일 위치를 알려줍니다.

2. 하이버네이트 설정 파일 만들기

<!DOCTYPE hibernate-configuration SYSTEM
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <mapping class="springsprout.domain.Member" />
        <mapping class="springsprout.domain.Comment" />
        <mapping class="springsprout.domain.Resource" />
        <mapping class="springsprout.domain.Right" />
        <mapping class="springsprout.domain.Role" />
        <mapping class="springsprout.domain.wiki.Histories" />
        <mapping class="springsprout.domain.wiki.History" />
        <mapping class="springsprout.domain.wiki.WikiDocument" />
        <mapping class="springsprout.domain.study.Study" />
        <mapping class="springsprout.domain.study.Presentation" />
        <mapping class="springsprout.domain.study.Meeting" />
        <mapping class="springsprout.domain.study.Attendance" />
        <mapping class="springsprout.domain.seminar.Seminar" />
        <mapping class="springsprout.domain.seminar.SeminarComer" />
        <mapping class="springsprout.domain.notice.Notice" />
        <mapping class="springsprout.domain.main.Graffiti" />
        <mapping class="springsprout.domain.file.UploadFile" />
    </session-factory>
</hibernate-configuration>

애노테이션기반으로 설정한 경우에는 위와 같이 애노테이션으로 맵핑한 클래스들을 알려줍니다.

3. 하이버네이트 프로퍼티 추가하기

hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.username=***
hibernate.connection.password=***
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=***

이런 설정을 프로퍼티 파일에 추가하거나 새로운 프로퍼티 파일을 만들어서 추가해줍니다.

끝!!!

이제 hbm2ddl 골을 실행할 수 있습니다.

제가 원한건 새로운 스키마용 ddl이 아니라, 기본 DB에서 수정할 것들만 알려주는 수정용 ddl인데 어떻게 설정해야 되는지 잘 모르겠군요. 그런 기능을 지원해주는 건지 아닌지도 몰겠고.. componentProperties를 보면 update 속성이 있긴한데, 이 녀석에 true를 줘버리면 ddl 자체가 안 만들어집니다. @_@;;


신고
top







티스토리 툴바