Whiteship's Note


The problem of subtypes

Hibernate/study : 2007.02.14 20:58


참조 : Java Persistence with Hibernate

객체에서는 상속이라는 것이 있는데 DB에는 그런게 없기 때문에 발생하는 문제입니다.

객체는 클래스라는 타입이 있고 이러한 타입이 상속되는 반면에 DB에 있는 Table은 type이 아니기 때문에 supertable 이나 subtable 같은 단어는 없습니다. 5장 5.1 "Mapping class inheritance"(p192)에서 이 문제에 대한 해결 방법이 나와 있습니다.

사용자 삽입 이미지

만약에 위와 같은 상속 구조를 DB로 표현하는 방법으로 책에서는 네가지 방법(크게 세가지)을 소개하고 있습니다.

1. Table per concrete class(with implicit polymorphism)

사용자 삽입 이미지
상속의 특징 중에 상위 클래스의 속성을 물려 받는 특징은 살렸지만... 다형성은 이용하지 못하겠습니다. 또한 상위 클래스의 속성이 변하게 되면 이런 테이블들 또한 일일히 변하게 되어야 하기 때문에 난감할 수 있겠습니다.

다형성이 필요없고 상위 클래스의 변동이 거의 없는 경우에 사용할 수 있겠습니다.

2. Table per concrete class(with unions)

사용자 삽입 이미지
매핑을 1번과는 조금 다른 방법으로 하지만 테이블의 구조는 1번과 거의 같은 구조의 스키마를 보이게 됩니다. 상위 클래스에 있는 속성들을 중복해서 선언하지 않고 <union-subclass> 태그를 이용해서 매핑 시킬 수 있습니다. 이 때 테이블의 주키도 역시 공유가 되기 때문에 같게 됩니다. 그리고 다형성을 이용할 수 있습니다.

3. Table per class hierarachy

사용자 삽입 이미지
가장 단순하고 성능도 좋은 매핑 전략입니다. 아예 하나의 테이블 안에 넣어 뒀기 때문에 다형성을 사용할 수 있으며 표현하기도 간단합니다.

그런데 하위 클래스들의 속성들은 전부 nullable이어야 한다는 제약이 있습니다. 생각해보면 당연합니다. Employee에 대한 정보를 넣고 싶은데 PartTimeWorker에 대한 정보가 없다고 못 넣는 다는 건.. 좀.....그렇쵸. 그리고 WORKER_TYPE 과 같은 구분자가 필요한데요. 이건 객체에 표시하진 않고 DB에서만 사용됩니다.

그리고 주키 아닌 속성에 종속되는 컬럼 들이 있기 때문에 정규화를 만족시키지 못한다는 것 역시 단점입니다.

4. Table per subclass

사용자 삽입 이미지

상속을 외례키를 사용한 관계로로 표현하는 방법입니다. 3번의 정규화 문제가 해결 됐다는 것이 장점이고 다형성은 join을 사용해서 가능합니다. 구분자도 필요없게 되었습니다. 하지만 맵핑 설정하는 것이 조금 복잡하네요. ~.~ 그리고 복잡한 상속 구조에서의 성능이 굉장히 안좋은 것 같습니다.

이 들 여러 전략들 중에 어느것을 사용할 지는 그때 그때 다르겠지만 3번과 4번이 가장 자주 사용될 듯 한 기분입니다.

'Hibernate > study' 카테고리의 다른 글

숙제 3  (4) 2007.03.01
The paradigm mismatch  (0) 2007.02.16
The problem of data navigation  (0) 2007.02.16
Problems relating to associations  (0) 2007.02.16
The problem of identity  (0) 2007.02.16
The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
top


The problem of graularity

Hibernate/study : 2007.02.14 16:06


참조 : Java Persistence With Hibernate

객체는 덩어리의 사이즈가 다양하고 DB에는 덩어리라고 할 수 있는 것이 테이블과 레코드밖에 없기 때문에 생기는 불일치를 말합니다.

덩어리 사이즈에 대한 이해가 쉽지 않았습니다. 예전에 corse-grained와 fine-grained에 대해서 OpenSeed 온라인 강좌에 댓글로 질문을 올렸었는데요. 그 때 승택님께서 답변을 해주셨지만 사실..그땐 잘 이해를 못했었습니다. 지금 다시 보니까 이해가 되는 것 같습니다.

사용자 삽입 이미지

그림에 보이듯이 User는 알갱이가 크다고 합니다. 반면에 Address는 알갱이가 작다고 합니다. 좀 더 자세히 살펴 보자면 다음과 같이 그릴 수 있겠네요.

사용자 삽입 이미지

저기 있는 것들을 단순하게 객체의 속성은 필드로 클래스는 테이블로 매칭시키기에는..뭔가 안맞는 것 같은 느낌이 드는데요. 이걸 해결하는 방법은 p177쪽 부터 설명이 나옵니다.

component라는 것을 사용한다고 하는데요. DDD quickly에서 보았던 Value Object가 나옵니다. 즉 identity를 가질 필요가 없고 값으로써 존재가치가 있는 개체 같은데요. 위에서 Address나 name이 그런 경우에 해당하지 않을까 생각해 봅니다. Account는 고유한 객체를 식별할 필요가 있게 느껴져서요.

'Hibernate > study' 카테고리의 다른 글

The paradigm mismatch  (0) 2007.02.16
The problem of data navigation  (0) 2007.02.16
Problems relating to associations  (0) 2007.02.16
The problem of identity  (0) 2007.02.16
The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
top


9. Tag만들기



CustomTag를 공부 하다가 느낀 점은.. 'servlet으로 html 코드 뿌리는 것 같다.', '복잡하네..언제는 뭐 상속 받고 언제는 뭐 상속 받고...어떤거 구현해줘야 하고 뭐를 리턴 해줘야 하고,,,,'

그런데 TagFile을 사용하면 매우 단순하게 태그를 만들 수 있었습니다.

1. Tag로 만들 부분 물색.
2. Tag를 만들었다는 가정하에 Tag를 사용해서 변경.
3. Tag 파일 작성.
4. 확인.

2번 다음에 확인하고 5. 수정하고 싶은 부분 수정하고 다시 확인 요거만 추가 하면 TDD랑 많이 닮은 것 같네요.

1. Tag로 만들 부분 물색.
사용자 삽입 이미지
2. 먼저 위에 있는 빨간색 부분을 다음과 같이 Tag가 있다고 생각하고 바꿔줍니다.
사용자 삽입 이미지
3. 그리고 WEB-INF/tags/os 안에 새로운 태그를 정의해 줍니다. page라는 태그명을 사용했기 때문에 page.tag라는 파일을 작성합니다.
<%@ attribute name="title" required="true" %>
<html>
    <head>
        <title>${title}</title>
        <link rel="stylesheet" type="text/css" href="/css/style.css" />
    </head>
    <body>
        <jsp:doBody />
    </body>
</html>

JSP 페이지 지시자를 사용해서 태그의 속성을 나타내고 EL태그로 원하는 위치에 사용하면 됩니다. 몸체가 있는 태그라면 하늘색 부분 처럼 몸체가 들어갈 부분에 <jsp:doBody /> 태그를 사용해 주면 됩니다. 이밖에도.. JSTL의 <c:set /> <c:if /> 이런 태그들을 이용해서 속성값에 기본 값을 setting하고 조건에 따라 값을 바꿀 수 있습니다.

4. 확인하기.
사용자 삽입 이미지
이런 에러가 납니다. title이 필수 속성이라고 했는데 왜 안넣어줬느냐!! 라는 것인데.. 전 넣는다고 넣어는데?? 라고 생각하고 소스를 다시 보니.. titile 라고 오타를 쳤네요. ㅠ.ㅠ

사용자 삽입 이미지
OK! 수정하고 새로고침을 해보니깐 제대로 나왔습니다.

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top


Tag를 만들어 쓰면 좋은 이유



1. 유지 보수가 편해집니다.
=> 한 곳(Tag를 정의한 곳)에서 수정을 하면 싹~ 바뀌기 때문에 편리합니다. 물론 화면에 특화 시켜서 Tag를 잘 정의 해 놓았기 때문에 가능한 일일 것입니다.

2. 웹 표준을 지키는데 유리해 집니다.
=> 웹 표준 담당자가 Tag 정의 한 부분을 손봐 주시고 다른 개발자는 신경쓰지 않고 개발을 해도 됩니다. Seperation of Concern이 이루어 지는거죠.

3. 성능에는 문제가 없습니다.
=> 처음에 자바 파일을 컴파일 해야 하기 때문에 조금 느리지 그 이후로는 오히려 컨테이너에서 캐슁하고 있기 때문에 HTML 태그를 쓰는 것보다 빠르다고 합니다.

4. 코드의 가독성이 높아집니다.
=> 화면에 특화 시켜서 나눠 놓았기 때문에 눈에 훨씬 잘 들어오겠죠.

5. 기타 등등등...
=> 좋은 것 같아요.

top

TAG tag

Custom Tag 만들기

Hibernate/study : 2007.02.07 09:52


참조 : http://www.javastudy.co.kr/docs/lec_javaweb/jsp/chapter5.pdf

1. Tag Handler Class 만들기(TagSupport or BodyTagSupport 상속)
2. Tag Library Descriptor File 만들기(Tag 이름과 Tag를 정의한 클래스 등을 명시합니다.)
3. JSP에서 사용하기.(taglib 지시자에 url과 prefix 명시하기)

위 참조 문서에 나와있는 예제의 순서입니다.
1. Body와 속성이 없는 Tag
2. 속성이 있는 Tag
3. body가 있는 Tag
4. Optional Tag
5. Body 부분 조작하는 Tag
6. Body 부분 반복하는 Tag
7. 중첩 연관 Tag

개인적으로 1, 2, 3, 4 번 까지는 그런데로 이해가 되는 것 같은데 그 뒤로는 머리가 복잡해 지다가 7번에서 gg...

'Hibernate > study' 카테고리의 다른 글

The problem of data navigation  (0) 2007.02.16
Problems relating to associations  (0) 2007.02.16
The problem of identity  (0) 2007.02.16
The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
top


책을 샀습니다.

Hibernate/study : 2007.02.04 21:10


아마존에서 책을 사보긴 처음인데 제가 직접 사진 않았습니다. AJN(Agile Java Network)에서 '해외 서적 구매 대행'을 해줬기 때문에 완전 빠르고 싸게 구매할 수 있었습니다.

사용자 삽입 이미지
$59.99 짜린데 아마존에서 $39.59에 팔고 있습니다. 대강 4만원이 조금 안되는 돈으로 샀습니다. 그리고 배송이 불과 1주일 밖에 안걸렸다는거... 배송비가 대강 11달러 라고 했으니 만원이라고 하면 그래도 정가 보다 싸게 빨리 배송을 받은 겁니다. 영회형이 저 책을 2달 걸려서 받았다고 하니까 엄청나게 빨리 받은거죠.

그렇습니다. 여태까지 "책 산거 자랑하기"랑 "AJN 해외 서적 구매 대행" 광고였습니다.

'Hibernate > study' 카테고리의 다른 글

Problems relating to associations  (0) 2007.02.16
The problem of identity  (0) 2007.02.16
The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
top


DisplayTag1.1 예제 보기

Hibernate/study : 2007.01.30 22:40


1. 이 곳에서 displaytag1.1-bin 압축 파일을 다운로드 하고 압축을 풀면 아래에 있는 war파일이 보입니다.
2. 이클립스를 실행하고 패키지들이 있는 곳에서 빈곳을 오른쪽 마우스를 클릭해서 import를 클릭합니다.
사용자 삽입 이미지
3. import할 유형에서 war파일을 선택합니다.
사용자 삽입 이미지

4. 불러올 war파일의 경로를 찾아 줍니다.
사용자 삽입 이미지

5. Next를 클릭하면 아래와 같은 화면이 뜨는데요. 아무것도 선택하지 마시고 그냥 finish를 합니다.
사용자 삽입 이미지

6. 생성된 프로젝트를 우클릭 하시고 Run As -> Run on Server를 하면 예제들을 볼 수 있습니다.

'Hibernate > study' 카테고리의 다른 글

The problem of identity  (0) 2007.02.16
The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
top


DisplayTag 써보기

Hibernate/study : 2007.01.30 19:04


참조 :
http://displaytag.sourceforge.net/11/
http://blog.naver.com/jdkim528?Redirect=Log&logNo=140011759837

DispalyTag의 기능들을 사용해 보기 위한 기본 환경 세팅은 두번째 참조 링크에 있는 소스를 이용했습니다.

1. 기본적인 테이블 출력 <display:table name="members" />

<%
    request.setAttribute( "members", new MemberManager().getMembers(100) );
%>

<display:table name="members" />

사용자 삽입 이미지

2. 컬럼 이름을 명시적으로 주고 싶을 때는 <display:column property="멤버변수" title="Alias" />

<display:table name="members">
    <display:column property="name" title="이름" />
    <display:column property="email" title="이메일" />
</display:table>

사용자 삽입 이미지

3. 페이징 처리를 하고 싶을 때는 <display:table name="members" pagesize="10">

<display:table name="members" pagesize="10">
    <display:column property="name" title="이름" />
    <display:column property="email" title="이메일" />
</display:table>

사용자 삽입 이미지

4. 컬럼 별로 Soring이 가능하도록 설정 <display:column sortable="true">

<display:table name="members" pagesize="10">
    <display:column property="name" title="이름" sortable="true" />
    <display:column property="email" title="이메일" />
</display:table>

사용자 삽입 이미지

이밖에도 여러 기능을 할 수 있습니다.

'Hibernate > study' 카테고리의 다른 글

The problem of subtypes  (0) 2007.02.14
The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
top


Criteria에서 Join하기

Hibernate/study : 2007.01.29 20:11


참조 : http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

Member(1) --- (*)Messenger 의 관계에서 다음과 같이 데이타가 들어있습니다.

Member m1 --- Messenger msg1("seal", MSN)
Member m1 --- Messenger msg2("seal2", Skype)
Member m3 --- Messenger msg3("keesun", MSN)

이 때 "MSN 메신저가 있는 모든 멤버"를 가져 오려면 join을 해야 합니다. Criteria를 사용해서 Join을 하는 방법은 두 가지가 있습니다.

1. createCriteria() 메소드 사용하기.

    public void testCriteriaJoin1(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createCriteria("messengers")
                        .add(Restrictions.eq("m_type", messengerType));

        assertEquals(2, c.list().size());
    }

2. createAlias() 메소드 사용하기.

    public void testCriteriaJoin2(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createAlias("messengers", "msg")
                      .add(Restrictions.eq("msg.m_type", messengerType));

        assertEquals(2, c.list().size());
    }

여기까지만 봐서는 둘의 차이가 단순히 alias를 사용해야만 한다는 것 밖에 모르겠습니다.[각주:1]

"MSN 메신저를 가지고 이름이 keesun인 멤버"를 찾으려면 위 주건에 .add(Restriction.eq("name", "keesun")만 추가하면 됩니다. 이것을 맨 끝에 추가 해보면 둘의 차이를 알 수 있습니다.

1. createCriteria() 메소드를 사용.

    public void testCriteriaJoin1(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createCriteria("messengers")
                          .add(Restrictions.eq("m_type", messengerType))
                          .add(Restrictions.eq("name", "keesun"));

        assertEquals(1, c.list().size());
    }
=> Messenger에 name이라는 컬럼이 없다면서 HQE[각주:2]가 발생합니다.

2. createAlias() 메소드를 사용.
   
public void testCriteriaJoin2(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createAlias("messengers", "msg")
                      .add(Restrictions.eq("msg.m_type", messengerType))
                      .add(Restrictions.eq("name", "keesun"));

        assertEquals(1, c.list().size());
    }
=> 제대로 동작합니다.

createCriteria(String) 메소드 뒤에 붙은 add() 메소드 들은 해당 String 타입에 대항하는 컬럼에 참조하게 되고 createAlias(String, String)메소드 뒤에 붙은 add() 메소드들은 여전히 기본(this)이 상위에 있는 createCriteria(Class)에 있는 Class 타입을 나타냅니다.

1을 제대로 동작하게 하려면 추가한 문장을 s.createCriteria(KMember.class) 요것 바로 다음으로 이동시키면 됩니다.

2에서 좀더 명확하게 나타내려면 .add(Restrictions.eq("this.name", "keesun")); 이렇게 this를 추가해 주면 됩니다.

  1. 'msg.'을 빼고 실행하면 Member에 m_type이란 컬럼이 없다면서  Hibernate.QueryException이 발생합니다. [본문으로]
  2. Hibernate Query Exception [본문으로]

'Hibernate > study' 카테고리의 다른 글

The problem of graularity  (0) 2007.02.14
Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
top


숙제 2

Hibernate/study : 2007.01.26 21:15


1.  HTML 형태로 논의한 표준 화면 구성에 맞도록 전체 UI를 다시 재작성. (예외 케이스에 대처)

  • 화면의 유형
    • 메인 화면 : 타이틀 + 검색조건 + 버튼 + 그리드
    • 팝업 화면(입력/수정 화면) : 타이틀 + 입력폼 + 버튼
  • 검색 결과 화면에서 고려할 것
    • 검색 조건이 남아 있고, 북마크 했을 때 검색 결과 화면 보일 수 있도록 GET 방식의 Request 사용하기.
    • 검색의 결과 부분만 새로 고침 = 그리드 영역을 iframe으로 분리하기.
    • 기본 화면은 전체 데이터 뿌려주기.
    • 검색 조건이 늘어 날 수 있으므로 검색 버튼 추가.
  • 그리드에 필요한 기능
    • 컬럼 별로 정렬 기능
    • 페이징 처리
    • 체크 박스(다중 선택 가능)
    • 링크 달기
  • Messenger 정보 입력 방법
    • 한 화면에서 처리 하기 위해 입력할 수 있는 Messenger의 정보의 갯수를 세개로 제한.
  • Member - MemberGroup - Group 에서의 비즈니스 룰
    • 각 그룹의 등급은 세 가지. "대표 운영자", "운영 요원", "일반 회원"
    • Group을 만드는 사람이 "대표 운영자"가 됨. = Only one
    • Member는 Group에 기본으로 "일반 회원"으로 등록이 됨.
    • "대표 운영자"는 그룹에 있는 Member 들의 등급을 조정할 수 있슴.
    • "운영 요원"은 뭐하지??
    • 특정 그룹에 가입 or 탈퇴의 주체는 멤버쪽에서 결정 합니다.
    • 그렇다면 "너는 누구냐?"가 필요하네요. 로그인이 필요해짐. -> 멤버에 ID 는 email로 하고 비번은 새로운 필드가 필요함.

2. DisplayTag (김종대씨 사이트 참고)를 다운받아서 예제를 돌려볼 것.
http://displaytag.sourceforge.net/11/
http://blog.naver.com/jdkim528?Redirect=Log&logNo=140011759837

3. Spring2.0의 Form 태그 레퍼런스 메뉴얼 읽어볼 것.
http://static.springframework.org/spring/docs/2.0.x/reference/mvc.html#mvc-formtaglib

4. JSP 2.0에 추가된. TagFile 개발 사용법을 알아 둘 것.

5. 1~4에 너무 힘을 빼진 말고 Hibernate를 꾸준히 공부할 것.

'Hibernate > study' 카테고리의 다른 글

Custom Tag 만들기  (0) 2007.02.07
책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
top


HibernateTemplate

Hibernate/study : 2007.01.26 14:20


8.4. 기능구현 여기서 던졌던 의문에 실마리를 찾은 듯...

HibernateTemplate은 Spring에 있는 API로 Hibernate를 사용해서 데이타에 접근하는 것을 좀 더 편리하게 해주고 Checked Exception인 HibernateException을 Unchecked인 DataAccessException으로 바꿔 준다고 합니다.
    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        return getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session s) throws HibernateException, SQLException {
                Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                           .setParameter("name", "%" + name +"%");
                return q.list();
            }
        });
    }

    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        Session s = getSession();
        Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                      .setParameter("name", "%" + name +"%");
        return q.list();
    }

위나 아래나 같은 일을 하는 것 처럼 보이지만.. 아래는 Exception에 대한 고려도 없고 Session을 열고 닫아 주는 일을 수동으로 해줘야 하는 군요. HibernateTemplate API를 대강 읽어봤는데 역시 영어 실력이 OTL...

'Hibernate > study' 카테고리의 다른 글

책을 샀습니다.  (0) 2007.02.04
DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
top


8.4. 기능 구현



검색 기능을 구현해 봅니다.

1. Dao 테스트에 다음과 같이 "s"로 검색 했을 때 두명이 나올 것이라고 예상합니다. 이런 예상의 근거는 DBUnit을 사용해서 XML에 있는 Data를 넣어서 사용할 것이기 때문에 XML에 있는 데이타를 근거로 삼았습니다.

    public void testGetMembers() throws Exception{
        insertFlatXmlDataSet("test/src/keesun/kSampleData.xml");
        assertEquals(2, kMemberDao.getMembers("s").size());
    }

2. 그리고 이클립스를 보고 있으면 컴파일 에러가 발생하는 것을 확인할 수 있습니다. 당연하죠. getMembers(String)이라는 인터페이스가 MemberDao 에 없기 때문입니다. 만들어 주면 되죠.

public interface KMemberDao extends GenericDao<KMember, Integer>{

    public List<KMember> getMembers(String string);

}

3. 인터페이스에 추가해 줬더니 이젠 이걸 구현한 쪽에서 에러가 발생합니다. 이것을 구현해 주고 테스트의 결과 녹색불이 들어오면 구현이 끝납니다.

    @SuppressWarnings("unchecked")
    public List<KMember> getMembers(final String name) {
        return getHibernateTemplate().executeFind(new HibernateCallback(){
            public Object doInHibernate(Session s) throws HibernateException, SQLException {
                Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                           .setParameter("name", "%" + name +"%");
                return q.list();
            }
        });
    }

위 코드에서 getHibernateTemplate()으로 HibernateTemplate객체를 받아오고 이 객체의 executeFind() 메소드를 사용해서 자기가 할일을 남(HibernateCallback)을 시켜서 합니다.

구현을 아래 처럼 간단하게 할 수도 있는데요.
        Session s = getSession();
        Query q = s.createQuery("from k_Member m where m.name like :name order by m.name asc")
                      .setParameter("name", "%" + name +"%");
        return q.list();

callback을 사용하는 이유가 있겠죠? 궁금하네요~ *_*

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top


8.3. Criteria 공부하기



특정 Member의 검색을 할 때 이름만 입력할 수도 있고 이메일만 입력할 수도 있습니다. 입력 할 수 있는 곳이 여러 곳이면 둘 다 입력하거나 둘 다 입력하지 않을 수도 있습니다. 이럴 때 입력을 하느냐 안하느냐에 따라 쿼리가 달라지는데요. 이런것을 Dynamic Query라고 하는것 같습니다.

HQL을 이용해서 이러한 쿼리를 다음과 같이 작성할 수 있습니다.
    public void testDynamicQueryByHQL(){
        insertDatas();
        String name = "s";
        String email = null;

        StringBuffer sb = new StringBuffer("from k_Member m where 1=1");
        if(!StringUtils.isEmpty(name)) sb.append(" and m.name like :name");
        if(!StringUtils.isEmpty(email)) sb.append(" and m.email like :email");
        q = s.createQuery(sb.toString());
        if(!StringUtils.isEmpty(name)) q.setParameter("name", "%" + name + "%");
        if(!StringUtils.isEmpty(email)) q.setParameter("email", "%" + email + "%");

        assertEquals(2, q.list().size());
    }

위와 같은 내용의 쿼리를 Criteria를 사용해서 작성하면 다음과 같이 간결해 집니다. 그리고 @Entity의 name속성에 지정해 준 값을 사용하는 것이 아니라 진짜 클래스 명을 사용해야 합니다.
    public void testDynamicQueryByCriteria(){
        insertDatas();
        String name = "s";
        String email = "keesun@os.net";

        Criteria c = s.createCriteria(KMember.class);
        if(!StringUtils.isEmpty(email)) c.add(Restrictions.eq("email", email));
        if(!StringUtils.isEmpty(name)) c.add(Restrictions.like("name", "%" + name + "%"));

        assertEquals(1, c.list().size());
    }

Criteria의 add 메소드는 인자로 Criterion을 넘겨 주어야 하는데요. Restrictions라는 팩토리를 사용해서 Criterion을 받아 오게 됩니다. Restrictions 클래스에는 쿼리에 덧붙일 수 있는 여러 메소드들이 있습니다.

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top


8.2. HQL 공부하기



8.2.1. HQL 공부하기 - select절
8.2.2. HQL 공부하기 - where절
8.2.3. HQL 공부하기 - order by절
8.2.4. HQL 공부하기 - inner join

참조 : http://openframework.or.kr/JSPWiki/Wiki.jsp?page=Javacanhibernate7

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top

TAG HQL

8.2.4. HQL 공부하기 - inner join



insertDatas() 메소드에서 집어 넣는 데이타에서 Member와 Messenger의 모습을 보면 다음과 같습니다.

사용자 삽입 이미지

seal 멤버만 두개의 Messenger 정보를 가지고 있습니다. 이 때 inner join을 하면 다음과 같이 두개의 레코드가 생기게 됩니다.
사용자 삽입 이미지
inner join을 HQL로 하는 방법은 s.create("from Member m inner join m.messengers") 이렇게 콜렉션을 가리키면 됩니다.

public void testJoinHQL(){

       insertDatas();

       q = s.createQuery("from k_Member m inner join m.messengers");

       List<Object> result = q.list();

       // Member m1 | Messenger msg1("keesun", MSN)

       // Member m1 | Messenger msg2("keesun2", Skype)

       assertEquals(2, result.size());

       Object[] result1 = (Object[]) result.get(0);

       assertTrue(result1[0] instanceof KMember);

       assertTrue(result1[1] instanceof KMessenger);

       KMessenger msg1 = (KMessenger) result1[1];

       assertEquals("seal", msg1.getM_id());

       assertEquals(KMessengerType.MSN, msg1.getM_type());

}

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top


8.2.3. HQL 공부하기 - order by절



public void testOrderByHQL(){

       insertDatas();

       q = s.createQuery("select m.name from k_Member m");

       List<String> names1 = q.list();

       StringBuffer sb = new StringBuffer();

       for(String name : names1)

             sb.append(name);

       assertEquals("sealparadozzkeesun", sb.toString());

 

       q = s.createQuery("select m.name from k_Member m order by m.name");

       List<String> names2 = q.list();

       assertEquals(3, names2.size());

       assertEquals("keesun", names2.get(0));

       assertEquals("paradozz", names2.get(1));

       assertEquals("seal", names2.get(2));

}


위에 있는 테스트 코드를 보시면 원래 테이블에 들어있는 이름의 순서는 seal -> paradozz -> keesun 이였는데 두번째 쿼리에서 order by를 사용하고 보니 keesun이 첫번째로 나오게 되는 것을 확인할 수 있습니다.

'Hibernate > 주소록 만들기' 카테고리의 다른 글

9. Tag만들기  (0) 2007.02.12
8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
top

TAG HQL, order by

8.2.2. HQL 공부하기 - where절



가장 간단하게 Where 절을 사용한 HQL은 다음과 같습니다.
s.createQuery("from Member m where m.name = '기선'");

위에서 '기선'과 같은 부분을 파라미터화 하는 방법에는 두 가지가 있습니다.
1. ? 를 사용하는 방법과
2. :를 사용하는 방법이 있습니다.

1. s.createQuery("from Member m where m.name = ? "); 이렇게 파라미터화 할 부분을 ? 로 표시하고 fluent interface 형태로 구현해 놓았기 때문에 뒤에 연달아서 .setParameter(0, "기선"); 을 덧 붙여 주면 됩니다.

2. s.createQuery("from Member m where m.name = :name "); 이렇게 :뒤에 변수 처럼 사용할 이름을 적어주고 .setParameter("name", "기선"); 이렇게 덧붙여 주면 됩니다. 파라미터가 여러개라면 이렇게 이름을 줘서 사용하는 것이 가독성이 좋을 듯 합니다.
이 때 파라미터의 타입을 명확히 주고 싶다면 setString과 같은 메소드를 setParameter대신에 사용하면 됩니다.

3. and 를 사용해서 여러 개의 조건을 줄 수도 있습니다.
이 때 여러 개의 조건을 줄 때 쿼리 결과를 최소한으로 줄여주는 조건문을 앞에 두는 것이 좋습니다.

public void testWhereHQL(){

       insertDatas();

       q = s.createQuery("select m from k_Member m where name='keesun'");

       assertEquals(1, q.list().size());

       //1

       q = s.createQuery("select m from k_Member m where name = ?")

              .setParameter(0, "keesun");

       assertEquals(1, q.list().size());

       //2

       q = s.createQuery("select m from k_Member m where name = :name")

              .setParameter("name", "keesun");

       assertEquals(1, q.list().size());

       //3

       q = s.createQuery("select m from k_Member m where name like :name and email like :email")

              .setString("name", "%a%")

              .setString("email", "%os.net");

       assertEquals(2, q.list().size());

}

'Hibernate > 주소록 만들기' 카테고리의 다른 글

8.4. 기능 구현  (0) 2007.01.25
8.3. Criteria 공부하기  (0) 2007.01.25
8.2. HQL 공부하기  (0) 2007.01.24
8.2.4. HQL 공부하기 - inner join  (0) 2007.01.24
8.2.3. HQL 공부하기 - order by절  (0) 2007.01.24
8.2.2. HQL 공부하기 - where절  (0) 2007.01.24
8.2.1. HQL 공부하기 - select절  (0) 2007.01.24
8.1. DbUnit 사용하기  (0) 2007.01.24
8. DAO 기능 구현하기  (4) 2007.01.23
7.3. 새로운 타입으로 맵핑하기.  (0) 2007.01.22
7.2. 기존 코드 수정하기.  (0) 2007.01.22
top

TAG HQL, where절

8.2.1. HQL 공부하기 - select절



Session에 있는 createQuery(Sring) 메소드를 이용해서 HQL을 사용할 수 있습니다.

가장 간단한 HQL은 다음과 같습니다.
s.createQuery("from Member");

여기서 " "사이에 들어간 부분이 HQL로 SQL과는 차이가 있으며 클래스의 이름은 @Entity의 name속성에 지정한 값을 쿼리에서 사용해야 합니다.[각주:1]

select문 사용하기

1. 모든 멤버를 가져오고 싶을 때 select * from Member SQL에서 이렇게 썼는데요. HQL은 이렇게 쓰면 에러가 발생합니다. select m from Member m 처럼 마치 레퍼런스 변수 만들듯이 표현해 주어야 합니다.

2. 특정 변수만 가져오고 싶을 때는 select m.name from Member m 처럼 가져오고 싶은 필드 명을 m이라는 Member의 인스턴스를 통하여 가져오듯이 표현합니다.

3. 여러개의 변수를 읽어 오면(ex select m.name, m.email from Member) 배열의 리스트로 받아 옵니다. 근데 가져온 값을 사용하기가 좀 복잡하네요.

4. SQL 함수인 count, avg, sum, max, min등의 함수도 사용할 수 있습니다.

public void testSelectHQL() {

       insertDatas();

       //1

       q = s.createQuery("select m from k_Member m");

       assertEquals(3, q.list().size());

       //2

       q = s.createQuery("select m.name from k_Member m");

       List<String> names = q.list();

       assertEquals(3,  names.size());

       assertEquals("seal", names.get(0));

       //3

       q = s.createQuery("select m.name, m.email from k_Member m");

       List<Object> datas = q.list();

       Object[] line1 = (Object[]) datas.get(0);

       assertEquals("seal", (String)line1[0]);

       assertEquals("seal@os.net", (String)line1[1]);

       //4

       q = s.createQuery("select count(*) from k_Member");

       assertEquals(new Long(3), q.uniqueResult());

}

top


HQL과 @Entity에 있는 name 속성의 관계

Hibernate/study : 2007.01.24 17:14


ejb 3.0 spec 8장 제일 처음에 나오는 @Entity에 대한 설명을 찾아 보게 된 원인은 HQL을 작성하려다가 다음과 같은 형상이 벌어졌기 때문입니다.

@Entity
Member{}

이런 클래스가 있고 이 클래스에 대한 HQL을 작성할 때 다음과 같이 작성을 하면 에러가 발생합니다.

Session s;
s.createQuery("from member");

"" 안에는 HQL이라고 SQL과 비슷한 구문이 들어가지만 SQL은 테이블명과 컬럼명을 기준으로 작성하고 select가 있어야 하지만 HQL은 from만 필수 요소이고 클래스명과 멤버변수명으로 작성을 한다고 배웠습니다. 따라서 다음과 같이 작성해야 원하는 대로 작업이 수행됩니다.

s.createQuery("from Member");

문제는 @Entity의 속성중에 name 속성에 값을 줬을 때 발생합니다.

@Entity(name = "K_Member")
KMember{}

이런 클래스가 있을 때 클래스명을 사용해서 다음과 같이 HQL을 만들려고 해보지만
 
s.createQuery("from KMember");

KMember is not Mapped라는 에러 메시지를 볼 수 있습니다.

s.createQuery("from K_Member");

이렇게 @Entity의 name 속성에 지정한 이름으로 작성해야 원하는 결과를 얻을 수 있습니다.

결과적으로 HQL에서 쿼리를 작성할 때 @Entity 어노테이션의 name 속성에 들어가는 값을 사용해야 하며 대소문자를 구분합니다. @Entity의 name에 지정해 주는 값은 DB에서 테이블 명이 되기도 하지만 일치 하지는 않습니다. postgres에서 확인해본 결과 DB에 들어간 테이블 명은 k_member와 같이 전부 소문자로 바뀝니다. 따라서 클래스명이 바뀐다고 생각을 하는 편이 더 이해하기 쉬울 것 같습니다.

물개 선생님께서 알려 주셔서 테스트를 @Column의 name 속성을 주고 HQL을 작성할 때 name 속성에 넣은 값을로도 해봤습니다. 하지만 멤버변수들은 @Column의 name에 넣어준 값에 영향을 받지 않습니다. 멤버변수명으로 해야 HQL Query Exception이 발생하지 않습니다.

p157 에 간단하게 설명이 있습니다. @Entity의 name속성에 지정한 값은 쿼리에서 사용 되며 JPQL의 예약어 이면 안된다고 합니다.

'Hibernate > study' 카테고리의 다른 글

DisplayTag1.1 예제 보기  (0) 2007.01.30
DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
top

TAG @Entity, HQL

8.1. DbUnit 사용하기



1. 먼저 DB에 입력할 dataset을 xml 형태로 작성 합니다.

이 때 주의 하실 점은 Entity와 Attribute의 이름들은 Object의 식별자를 사용하는 것이 아니라 Relation에서 사용되는 이름으로 사용해야 합니다.


2. 입력한 샘플 데이타를 테스트할 메소드를 만들고 DbUnit을 사용하여 DB에 넣습니다.

public void testWithSampleData() throws Exception{

     insertFlatXmlDataSet("test/src/keesun/kSampleData.xml");

}


이상태에서 test를 돌려보고 DbUnit이 동작하는데 이상은 없는지 확인합니다. 만약 위에서 작성한 xml에 매칭되는 컬럼을 못찾을 경우 에러가 발생합니다.

3. 입력한 샘플을 기반으로 간단한 쿼리를 날려서 결과를 확인해 봅니다.

public void testWithSampleData() throws Exception{

      insertFlatXmlDataSet("test/src/keesun/kSampleData.xml");

 

      assertEquals(3, kMemberDao.getAll().size());

      assertEquals(2, kGroupDao.getAll().size());

      assertEquals(4, kMemberGroupDao.getAll().size());

      assertEquals(4, kMessengerDao.getAll().size());

}


테스트는 통과 합니다~ :)
좀더 복잡한 쿼리를 날리기 위해서는 HQL과 Criteria를 공부해야 합니다. 하지만 그다지 어렵지 않다는거~

사용자 삽입 이미지
top


Fluent Interface

Hibernate/study : 2007.01.24 00:14


참조 : http://www.martinfowler.com/bliki/FluentInterface.html
번역 : http://younghoe.info/1

오늘 OpenSeed 스터디를 통해서 알게 된 단어이자 어떻게 해석해야 할지 막막한 '흐르는 듯한 인터페이스'라고 하면 어울리려나..

code를 보시면 감이 팍 올 것 같습니다.

before
private void makeNormal(Customer customer) {
Order o1 = new Order();
customer.addOrder(o1);
OrderLine line1 = new OrderLine(6, Product.find("TAL"));
o1.addLine(line1);
OrderLine line2 = new OrderLine(5, Product.find("HPK"));
o1.addLine(line2);
OrderLine line3 = new OrderLine(3, Product.find("LGV"));
o1.addLine(line3);
line2.setSkippable(true);
o1.setRush(true);
}
after
   private void makeFluent(Customer customer) {
customer.newOrder()
.with(6, "TAL")
.with(5, "HPK").skippable()
.with(3, "LGV")
.priorityRush();
}

멋지지 않나요? DSL(Domain Specific Language)과도 관계가 있고 Value Object 이야기가 나오는걸 보니 DDD(Domain Driven Design)와도 관계가 있는 글 같습니다.

가독성 좋고, 코드 길이가 짧아져서 좋은 것 같습니다. 본문에 단점이라고 꼽은 것으로는 메소드 그 자체만 보면 의아해 할 수도 있다는 내용이 있었습니다. setter에 리턴타입이 표기 되기 때문에 그럴 수 있지요. 따라서 "연속되는 행위"에 활용이 되면 좋겠다는 내용이 있습니다.

Anyway 멋지네요.

'Hibernate > study' 카테고리의 다른 글

DisplayTag 써보기  (2) 2007.01.30
Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
top


8. DAO 기능 구현하기



5. 모델, DAO 까지 개발 공정
위에서 만들었던 DAO는 기본적이고 매우 널리 사용되는 기능만 있었기 때문에 검색을 하는등의 개발 대상에 특화된 기능을 구현하는 시간을 가졌습니다.

1. 테스트 데이타를 XML -> Table 로 바로 넣어 주는 DBUnit을 사용했습니다.
2. HQL 과 Criteria 를 공부했습니다.
3. Context[각주:1]를 공부했습니다.
  1. http 에서 사용하는 것은 전부 String이기 때문에 적절한 타입으로 변경해 주는 역할도 할 수 있고 객체 단위로 값들을 묶을 수 있는 녀석 [본문으로]
top


DbUnit

Hibernate/study : 2007.01.23 17:32


참조 : http://www.dbunit.org/index.html

Test 할 때 사용할 DB에 있는 값을 XML로 뽑아 내거나 XML에 입력한 데이타를 DB로 넣을 수 있는 오픈소스입니다. JUnit이랑 이름이 비슷한데 JUnit을 확장시킨 거라고 하네요.

사용하는 방법은 여기에 나와있지만 잘 모르겠습니다.
대강 본 바로는 xml에 각 테이블에 들어갈 데이타 들을 입력하고
FlatXmlDataSet 클래스를 이용해서 xml을 을 읽어들이고(ex. IDataSet)
읽어 들인 값을 집어 넣을 DB 커넥션을 설정(ex. IDatabaseConnection)해주면 DB에 들어가는 것 같습니다.
그리고 Assertion 이라는 클래스가 만들어져 있어서 ITable이나 IDataSet 끼리 assertEqulas 메소드를 사용해서 비교할 수 있습니다.

물개 선생님의 코드중 일부를 보시면 다음과 같습니다.  

public void testSampleData() throws Exception {

      insertFlatXmlDataSet("test/src/seal/sampleData.xml");

      assertEquals(3, memberDao.getAll().size());

      memberDao.getMembers("seal").get(0).getEmail());

      assertEquals(2, memberDao.getMembers("s").size());

}


맨 위에 첫줄로 xml에 입력 해 둔 데이타를 DB에 저장하고 그 뒤로는 DB에 들어간 값들을 가지고 테스트를 할 수 있습니다.

음~ 모든 필드들을 다 채워 넣은 다음에 다음과 같은 것들을 테스트 해보고 싶습니다.

  • Agile Java 그룹에 속한 멤버들 중에 이메일에 k가 들어가는 멤버 확인(Group->MemberGroup->Member)
  • keesun이라는 멤버가 속한 그룹의 이름 확인.(Member->MemberGroup->Group)
  • keesun이라는 멤버가 가진 이메일 주소 확인.(Member->Messenger)
  • Messenger 중에 MSN을 사용하지 않는 멤버들의 email.(Messenger->Member)

이렇게 해보면 연관관계가 제대로 되어 있는지 확인 할 수 있을 것 같습니다.

'Hibernate > study' 카테고리의 다른 글

Criteria에서 Join하기  (0) 2007.01.29
숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
top


7.3. 새로운 타입으로 맵핑하기.



@Type 어노테이션의 type과 parameters 속성에 다음과 같이 설정해 줍니다.

 @Column(nullable = false)
 @Type(type = "net.openseed.core.persist.hibernate.usertype.GenericEnumUserType", parameters = { @Parameter(name = "genericEnumClass", value = "keesun.model.enumeration.KMessengerType") })

 public KMessengerType getM_type() {
  return m_type;
 }

여기서 @Type이랑 @Parameter를 알아봐야겠습니다.

@Type 에 대한 Hibernate Reference에는 이렇게 쓰여있습니다.
@org.hibernate.annotations.Type overrides the default hibernate type used: this is generally not necessary since the type is correctly inferred by Hibernate. Please refer to the Hibernate reference guide for more informations on the Hibernate types.
기본 type을 재정의 하는데 사용되는 어노테이션이군요.

@Parameter에 대한 설명은 찾기가 조금 힘드네요. 레퍼런스를 보니까 @TypeDef라는 어노테이션 안에서 비슷하게 사용된 것을 볼 수 있었습니다.

HIA2판을 뒤져 봤습니다. 5.3.4 Creating a UserType 이라는 장부터 5.3.7 Mapping Enumeration에 걸쳐서 Hibernate에 있는 컬럼의 기본 타입이 아닌 새로운 타입으로 지정하고 싶을 때 위와 같은 방식을 사용한 것 같습니다.
top


7.2. 기존 코드 수정하기.



1. Messenger 클래스의 m_type 변수의 타입을 MessengerType으로 수정하기.

 KMessengerType m_type;

2. Getter, Setter코드 부분을 다음과 같이 수정합니다.

 public KMessengerType getM_type() {
  return m_type;
 }

 public void setM_type(KMessengerType m_type) {
  this.m_type = m_type;
 }

3. Test 코드에서 발생하는 에러도 수정합니다.

//KMessengerDaoTest.java
KMessenger m = KMessengerFixture.getAMessenger("keesun", KMessengerType.Skype);

//KMessengerFixture.java
public static KMessenger getAMessenger(String m_id, KMessengerType m_type)

이렇게 수정을 하는데에는 몇분이 채 소요되지 않으며 이클립스의 도움이 큽니다. 에러가 나는 부분에는 전부 빨간 불이 들어오고 Ctrl + 1로 제안을 볼 수 있어서 매우 편했습니다.

top


7.1. MessengerType 클래스 작성.



1. GenericDao 상속 받기.

public class KMessengerType extends GenericEnum

2. GenericDao<클래스명, 값의 타입> 입력하기.

public class KMessengerType extends GenericEnum<KMessengerType, String>

3. 생성자는 private 타입으로 변경하기.

    private KMessengerType(String value, String descr) {
        super(value, descr);
    }

4. 원하는 enum을 public final static 변수로 생성하기.

    public static final KMessengerType MSN = new KMessengerType("M", "MSN");
    public static final KMessengerType NATE = new KMessengerType("N", "Nate On");
    public static final KMessengerType GOOGLE = new KMessengerType("G", "Google Talk");
    public static final KMessengerType Skype = new KMessengerType("S", "Skype");

5. DB에 어떻게 저장되어야 할지 나타내 주는 getType 메소드 정의하기.

    public static int getType() {
        return Types.CHAR;
    }

전체 코드 보기
top


7. Enumeration 사용하도록 리팩터링



Messenger의 Type과 Member의 Role에 특정 값만 들어 갈 수 있도록 하는 것이 보다 효율적으로 판단되어 Enum을 사용하도록 수정합니다.

1. GenericEnum 을 상속 받는 MessengerType고 RoleType 클래스를 작성합니다.

2. Messenger 클래스와 MemberGroup 클래스에 있는 messegerType과 role변수의 타입을 변경합니다.

3. 새로운 타입으로 매핑하기.
top


Hibernate에서 쿼리 날리는 방법

Hibernate/study : 2007.01.19 16:47


참조 :
http://openframework.or.kr/JSPWiki/Wiki.jsp?page=Javacanhibernate7
http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Session.html

1. HQL 사용하기.

 Query

createQuery(String queryString)
          Create a new instance of
Query for the given HQL query string.

 

2. Criteria API 사용하기.

 Criteria

createCriteria(Class persistentClass)
          Create a new
Criteria instance, for the given entity class, or a superclass of an entity class.

 Criteria

createCriteria(Class persistentClass, String alias)
          Create a new
Criteria instance, for the given entity class, or a superclass of an entity class, with the given alias.

 Criteria

createCriteria(String entityName)
          Create a new
Criteria instance, for the given entity name.

 Criteria

createCriteria(String entityName, String alias)
          Create a new
Criteria instance, for the given entity name, with the given alias.

 

3. 그냥 SQL 문 날리기.

 SQLQuery

createSQLQuery(String queryString)
          Create a new instance of
SQLQuery for the given SQL query string.

 

'Hibernate > study' 카테고리의 다른 글

숙제 2  (0) 2007.01.26
HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
top


객체들의 상태 변화(in Hibernate)

Hibernate/study : 2007.01.19 16:16


참조 : http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Session.html

OpenSeed의 물개 선생님께서 지난 강의에서 Hibernate의 특징 중에 하나로 Transparent Persistency라는 용어를 설명해 주셨습니다. 어떤 객체가 자기 자신이 Persistent 객체임을 전혀 모르는 상태에서 Persistent와 관련된 일들이 벌어지기 때문에 "투명한 영속성"이라고 한다고 이해를 했습니다.

그렇다면 누가 어떤 객체를 Persistent와 관련된 일을 처리해 주는가? Persistent Manager가 그 일을 해 주는데 그러한 역할을 하는 대표적인 녀석으로 Session이 있다는 설명도 해주셨습니다.

Hibernate에서 사용하게 되는 객체는 Transient, Persistent, Detached 상태 중에 하나로 존재 하게 되는데 Session에 있는 메소드를 사용함에 따라 그 상태가 바뀌게 됩니다.

위 API에 있는 것을 그림으로 옮기면 다음과 같습니다.
사용자 삽입 이미지

merge()는 그리기가 불편해서 안그렸는데요. Tarsient나 Detached상태에서 merge()를 호출하면 '새로운 Persistent'가 된다고 합니다.

'새로운 Persistent'는 해당 객체가 주키는 가졌지만 아직 DB에는 들어가지 않은 상태를 말합니다.

지난 번에 각각의 객체들의 특징을 살짝 공부했던 적이 있네요.
Transient Object
Persistent Object
Detached Obejct

'Hibernate > study' 카테고리의 다른 글

HibernateTemplate  (0) 2007.01.26
HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
top


숙제

Hibernate/study : 2007.01.19 00:36


1. GenericDao에서 사용한 Session의 메소드들 조사 & 객체의 상태 변화
- 객체들의 상태 변화
- Hibernate에서 쿼리 날리는 방법

2. DB에 test를 하려면 test를 위한 값이 있어야 하는데 이런 것들을 exel이나 xml에 데이타를 입력해서 test용으로 쓸 수 있도록 도와주는 오픈소스 조사 & 어떻게 사용할지 고민
- DbUnit

3. Yahoo의 YUI 조사.
- YUI

http://blog.1nooncorp.com/attach/0315/060315160206236729/283486.jpg

'Hibernate > study' 카테고리의 다른 글

HQL과 @Entity에 있는 name 속성의 관계  (0) 2007.01.24
Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
top

TAG 숙제



: 1 : 2 : 3 : 4 : 5 : 6 : 7 :