By zmzizi

Hibernate concepts for Beginners-1 #

- POJO 설계와 XDoclet 을 이용한 hbm 파일 생성

1) POJO 설계#

1. 가능한 POJO 의 property = 테이블의 컬럼 이 되도록 한다.

2. POJO 의 property 들은 될 수 있으면 기본형이 아닌 객체 타입으로 선언한다.
=> 해당 컬럼의 데이터가 존재하지 않을 시(null), 기본형에는 null 타입 데이터가 존재하지 않기 때문에 매핑 에러가 난다.

3. 1:n 의 포함관계일 경우, 양쪽 모두에 관계를 정의해 두는 것이 좋다.
예를 들면 Woman(1) - Clothes(n) 관계의 POJO 가 있을 때, Woman 클래스에는 Clothes 의 컬렉션을, Clothes 클래스에는 Woman 클래스를 정의해 둠으로써 양자의 관계를 명확히 하는 것이 좋다.

2) hbm 파일 생성 : XDoclet 을 사용할 경우의 핵심 태그 및 속성들 중심으로#

1. 헤더
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" 
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

2. hibernate-mapping 태그

<hibernate-mapping></hibernate-mapping>

hibernate-mapping 태그는 Woman.hbm.xml 파일의 최상위 태그이다.

3. class 태그

<class name="test.Woman" table="WOMAN"></class>

클래스 태그는 해당 POJO 클래스명과 매핑되는 테이블명을 기술한다.

4. id 태그

<id name="womanId" column="womanid" type="long" length="20" unsaved-value="null"></id>

테이블의 pk 가 되는 id property 를 정의하는 태그이다.

  • name : id property 의 이름
  • column : id property 와 매칭되는 테이블의 해당 컬럼
  • type : id property 타입(기본형, 객체형 등이 올 수 있다.)
  • length : id property 의 최대길이이자 컬럼의 길이
  • unsaved-value : any|none|null|id_value 값이 올 수 있으며, default 값은 null 이다. 이것은, Hibernate 의 saveOrUpdate() 메써드가 호출되었을 시, 각각 save 와 update 를 판단하는 기준을 설정하는 것으로써 다음의 의미를 가진다.
    1. null : id 가 null 이면 save, 아니면 update
    2. any : 항상 save 만을 호출
    3. none : 항상 update 만을 호출
    4. id_value : 특정 id_value 일 경우에만 update

5. generator 태그

<generator class="native"></generator>

id 태그의 하위 태그로 항상 같이 사용된다. id 를 생성하기 위한 방법(generator)을 정의하는 태그로, increment, sequence, identity, native, assigned, foreign 등의 방법이 있다.

  • increment : MySQL 의 auto increment 기능을 말한다. 이 방법이 사용가능한 DBMS 는 MySQL, PostgreSQL and DB2 등이 있다. 단, cluster 환경에서는 사용해서는 안된다.
  • sequence : Oracle 에서 사용되는 sequence 기능을 말한다. DB2, PostgreSQL, Oracle, SAP DB, McKoi 의 sequence 혹은 Interbase 의 generator 를 사용한다.
  • identity : DB2, MySQL, MS SQL Server, Sybase, HypersonicSQL 에서의 identity 컬럼 을 지원한다.
  • native : 기반한 데이터베이스의 종류에 따라, identity, sequence, hilo 에서 취사선택한다. 예를 들어, MySQL 의 경우 identity, Oracle 의 경우 sequence 가 자동선택된다. 단, PostgreSQL, DB2 에서의 테스트에서 native 로 할 경우 오류가 발생한다는 보고가 있었고, 이들 DBMS의 경우 increment 로 설정하니 테스트는 성공적이었다고 한다. 자세한 내용은, http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuseOnDB2 의 2/5 지점의 NOTE 를 참조하길 바란다.
  • assigned : save() 하기 이전에 사용자가 직접 id 값을 지정해 주는 경우이다. 예를 들어, 회원의 주민번호로 id 값을 설정할 경우일텐데, Hibernate 에서는 이런 컬럼 외에 자동생성 id 컬럼을 반드시 두는 것을 권고하고 있다.
  • foreign : 연관관계에 있는 다른 POJO 의 id(즉, foreign key)를 자신의 id 로 두는 방법이다. 개인적인 의견으로는, Hibernate 라는 OR Mapping Tool 의 성격상 native 를 기본적인 generator 로 설정하되, PostgreSQL, DB2 의 테스트에서 나왔듯이 문제가 발생할 경우, 다른 generator 를 선택하는 것이 좋을 것이라 생각된다.

6. property 태그

<property name="name" type="java.lang.String" column="name" length="50"/>

property 태그는 POJO 클래스의 해당 property 의 각종 속성을 정의한다.

  • name : property 의 이름
  • type : property 의 타입(기본형 혹은 객체형)
  • column : 매핑될 테이블의 해당 컬럼명
  • length : property 의 최대길이이자 컬럼의 길이

7. many-to-one 태그

<many-to-one name="woman" class="test.Woman" cascade="none" outer-join="auto" column="womanid"/>

many-to-one 태그는 Clothes 클래스에서 Woman 클래스를 바라보는 입장, 즉, n 클래스에서 1 클래스를 정의하는 방식이다.

  • name : Clothes 클래스 내에서 Woman 클래스를 property 로 정의할 때의 이름, 즉 private Woman woman; 이라고 정의 할 때의 변수명이다.
  • class : Woman 클래스의 full qulified name.
  • cascade : all|none|save-update|delete 의 값이 있으며, 소유관계의 클래스의 변동사항이 있을 때, 하위관계에 있는 현재 클래스도 변경될 것인지 여부를 설정한다. default 는 none 이다. all(항상 변경), none(절대 변경안함), save-update(save-update 시), delete(삭제시) 일반적으로 none 혹은 delete 가 많이 사용될텐데, 해당 Woman instance 가 삭제될 경우, 그 instance 에 연관된 Clothes 도 삭제할 것인가(delete) 아닌가(none) 의 정책결정에 달려 있다.
  • outer-join : true|false|auto. default 는 auto 이며, hibernate.use_outer_join 이 세팅되었을 경우,outer join 을 할 것인지 여부를 정한다.
  • column : 자신의 테이블에 참조 클래스의 fk 컬럼명을 설정한다. 대개 참조 클래스의 pk 컬럼명과 일치시킨다.

8. one-to-one 태그
1:n 관계가 아닌 1:1 관계라는 것을 제외하고는 위의 many-to-one 태그와 많이 다르지 않다. 서로 다른 속성이 존재하기는 하지만, 대부분 선택사항이기 때문에 필요시 확인만 하면 되는 수준. 단, 한가지 중요한 사항은 one-to-one 관계일 경우, 한 클래스의 id 가 다른 클래스의 id 가 되는 관계, 즉 id 태그를 설정함에 있어서, generator class="foreign" 으로 설정하도록 한다.

     <class name="woman" table="WOMAN">
         <id name="womanId" 컬럼="womanid">
             <generator class="foreign">
                 <param name="property"></param>
             </generator>
         </id>

         ...

         <one-to-one name="employee" class="Employee" constrained="true"/>
     </class>

개인적으로 사용해보지 않아서 확실히 모르므로 소개만 하고 넘어감... ┌( -_-)┘

9. bag 태그

<bag name="clothes" table="CLOTHES" lazy="true" cascade="all"></bag>

collection 을 나타내는 태그는 set, map, list, array, bag 등이 있다.
나의 경우, 1:n 관계를 표현할 때, 포함된 컬렉션 클래스들은 모두 list 로 정의하였고, hbm 파일상의 매핑은 bag 태그를 사용하였다. list 태그를 사용해도 괜찮았겠지만, bag 태그가 좀 더 광범위하게 사용된다고 이해했기 때문에 bag 태그를 사용하였다.

  • name : 컬렉션 property 의 이름
  • table : 해당 컬렉션 데이터가 매핑하고 있는 테이블명
  • lazy : true|false default 는 true. 늦은 초기화 설정여부를 나타낸다. 여기에서의 늦은 초기화란, 예를 들어,특정한 Woman instance 를 가져왔을 때, 그 Woman 이 가지고 있는 Clothes 데이터까지 모두 가져오지 않으며, 그 Woman instance 에서 getClothes 메써드가 호출되었을 시에 Clothes 데이터를 가져오는 것을 말한다. 즉, 실제로 해당 데이터에 접근을 했을 때, 데이터를 로딩하기 때문에, 늦은 초기화라고 부른다. 만약, 이 설정이 false 로 되어 있다면, Woman instance 를 가져오는 즉시, 포함관계의 Clothes 데이터도 가져오게 된다. 이는 불필요한 데이터 액세스를 줄이기 위한 정책적인 결정에 따른다. 그런데, 이러한 늦은 초기화가 가능한 것은 트랜잭션이 관리되는 범위까지에서이다. 즉, Hibernate 를 독립적으로 사용시에는 Session 이 닫히기 이전, Spring 과 함께 사용시에는 applicationContext.xml에서 설정한 Service Transaction 클래스 내까지만 늦은 초기화가 가능하며, 이때까지 초기화를 하지 않은 상태로 Action 클래스 혹은 JSP 화면에서 데이터를 액세스 하려고 하면 LazyInitializationException 이 발생하게 된다. 따라서, 실제로 사용해야 하는 데이터라면 반드시 동일 Session 내에서 반드시 초기화 과정을 거쳐야만 한다.
  • cascade : all|none|save-update|delete|all-delete-orphan default 는 none 이며, 포함하고 있는 클래스의 변경시 컬렉션에 들어 있는 데이터들의 변경 설정을 결정한다.

10. key 태그

<key column="womanid"></key>

컬렉션의 fk 컬럼명. 해당 클래스에서 many-to-one 에 정의된 테이블 컬럼명이기도 하다.

11. one-to-many 태그

<one-to-many class="test.CLOTHES"/>

컬렉션의 데이터가 되는 클래스. full qualified name 으로 표기한다.

3) XDoclet을 사용한 hbm 파일 생성 Tips#

  1. hbm 파일 생성은 XDoclet 태그를 이용하여 자동생성 하는 것을 원칙으로 한다.
  2. Hibernate XDoclet 태그 사용은 http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html 를 참조.
  3. 클래스 레벨 태그는 클래스명 앞에, 메써드 레벨 태그는 getter 메써드 앞에 기술하되, 상위 태그가 위에 오도록 한다.
  4. 특정한 데이터 handling 등을 위해 테이블의 컬럼 이 아님에도 부득이하게 POJO 의 property 로 추가되어야 할 경우, 해당 property 에는 XDoclet 태그를 달아서는 안된다. XDoclet 태그를 달면 테이블의 컬럼과 매핑시 오류가 발생한다.
  5. build.xml 에 추가시켜 두면 유용한 Hibernate 관련 task
  • xdoclet 사용시 필요한 library path : ${classes.home} 등 알만한 변수는 생략

<path id="xdoclet.lib.path">
  <fileset dir="${catalina2.home}/common/lib">
     <include name="*.jar"/>
  </fileset>
  <fileset dir="${xdoclet.home}/lib">
     <include name="*.jar"/>
  </fileset>
  <fileset dir="${build.webinf.dir}/lib">
     <include name="*.jar"/>
  </fileset>
</path>

  • hbm 파일 만드는 task

<target name="make-hbm" depends="">
  <taskdef
    name="hibernatedoclet"
   classname="xdoclet.modules.hibernate.HibernateDocletTask"
   classpathref="xdoclet.lib.path"
  />
  <hibernatedoclet destdir="${classes.home}">
    <fileset dir="${src.home}">
      <include name="**/*.java" />
    </fileset>
    <fileset dir="${src.home2}">
      <include name="**/*.java" />
    </fileset>
    <hibernate version="2.1" />
  </hibernatedoclet>
</target>

  • hbm 파일의 내용대로 DBMS 에 테이블을 생성하는 task

<target name="schemaexport" depends="make-hbm">
  <taskdef name="schemaexport"
 classname="net.sf.hibernate.tool.hbm2ddl.SchemaExportTask"
 classpathref="compile.classpath"/>

    <schemaexport properties="build.properties"
        quiet="no"
        text="no"
        drop="no"
        delimiter=";"
        output="${basedir}/doc/programDesign/DB_Schema/schema.sql">
    <fileset dir="${classes.home}">
      <include name="**/*.hbm.xml"/>
    </fileset>
  </schemaexport>
</target>

  • 특정 이름의 sql 파일을 실행시켜 테이블에 초기 데이터를 입력하는 task

<target name="init-sql" depends="">
  <sql driver="${hibernate.connection.driver_class}"
       url="${hibernate.connection.url}"
       userid="${hibernate.connection.username}"
       password="${hibernate.connection.password}"
       print="yes"
       output="${basedir}/doc/init_sql_result.log"
       classpathref="compile.classpath">
    <fileset dir="${basedir}/doc">
      <include name="*init*.sql"/>
    </fileset>
  </sql>
</target>

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-1) was last changed on 06-Apr-2006 09:45 by UnknownAuthor