By 크캬캬

하이버네이트 입문
#

닉 휴데커
(원문 : http://www.systemmobile.com/articles/IntroductionToHibernate.html)

엔터프라이즈 어플리케이션 개발에 있어서 중요한 부분은 선택된 데이터베이스로부터 객체를 저장하거나 가져오는 퍼시스턴스 계층을 만들거나 유지/보수하는 것에 관련된다.
많은 조직(단체, 회사)들은 종종 버그가 있는 자체제작한 퍼시스턴스 계층을 복구한다.
만약 하위의 데이터베이스 스키마가 변경된다면, 나머지 어플리케이션들에도 그 변경사항들을 비용을 들여 적용시켜야 한다.
하이버네이트는 자바 어플리케이션을 위한 강력한 객체-관계 퍼시스턴스 프레임워크를 제공함으로써 이러한 격차를 메꿔줄 것이다.

하이버네이트는 복합관계는 물론, 컬렉션들과 객체 관계를 지원한다.
객체에 대한 저장은 물론이고, 하이버네이트는 데이터베이스로부터 객체를 가져오기 위한 방대한 쿼리문을 제공하며, 효율적인 캐쉬 계층과 Java Management Extensions(JMX) 역시 지원한다.
사용자 정의 데이터 타입들과 복합 pk는 기존의 어플리케이션들을 지원하는데 추가적인 유연성을 더해줄 것이다.
하이버네이트는 Lesser GNU Public License 하에 출시되고 있다.
따라서 상업용 애플리케이션은 물론이고 오픈 소스 애플리케이션에도 충분히 사용할 수 있다.
하이버네이트는 오라클, DB2를 포함하여, 대중적인 오픈소스 데이터베이스인 PostgreSQL, MySQL 등 많은 데이터베이스를 지원한다. 또한, 활동적인 사용자 커뮤니티는 하이버네이트를 확장하거나 좀더 쉽게 사용할 수 있도록 지원 및 툴 등을 제공해준다.

이 기사는 2003년 12월에 출시된 하이버네이트 2.1 버전을 포함한다.


하이버네이트는 어떻게 작동하는가
#

바이트 코드 프로세싱이나 코드 생성이 아니라, 하이버네이트는 클래스의 퍼시스턴스 프로퍼티를 얻어오기 위해서 실시간 반영을 이용한다.
저장되는 객체는 퍼시스턴스 필드들과 관계들, 그리고 퍼시스턴스 객체의 모든 서브클래스들과 프록시들에 대한 설명을 제공하는 매핑 문서에 정의가 된다.
매핑 문서는 애플리케이션 기동시에 컴파일되고, 클래스에 필요한 정보를 가진 프레임워크를 제공한다. 뿐만 아니라 매핑 문서는 데이터베이스 스키마 또는 Stub 자바 소스 파일생성 등의 기능을 이용할 때 사용된다.
SessionFactory는 매핑 문서의 컴파일된 컬렉션으로부터 생성된다.
SessionFactory는 Session 인터페이스로 퍼시스턴스 클래스를 관리하기 위한 메커니즘을 제공한다.
Session 클래스는 퍼시스턴스 데이터 저장과 애플리케이션 간의 인터페이스를 제공한다. Session 인터페이스는, 사용자에 의해 관리되거나 하이버네이트에 의해 조정될 수 있는 JDBC 연결을 래핑하고 있고, 오직 하나의 애플리케이션 쓰레드에 의해서만 사용되도록 관리된다.


매핑 문서
#

우리는 예제로 Team, Player라는 두개의 시험 클래스들을 사용할 것이다.
이 클래스들에 대한 매핑은 아래와 같다.
<hibernate-mapping>
  <class name="example.Team" table="teams">
    <id name="id" column="team_id" type="long" unsaved-value="null">
      <generator class="hilo"/>
    </id>
    <property name="name" column="team_name" type="string"
        length="15" not-null="true"/>
    <property name="city" column="city" type="string" length="15" not-null="true"/>
    <set name="players" cascade="all" inverse="true" lazy="true">
      <key column="team_id"/>
      <one-to-many class="example.Player"/> 
    </set>
  </class>
</hibernate-mapping>
Figure 0 - example.Team mapping document

<hibernate-mapping>
  <class name="example.Player" table="players"
    <id name="id" column="player_id" type="long" unsaved-value="null">   
      <generator class="hilo"/>
    </id> 
    <property name="firstName" column="first_name" type="string" length="12" not-null="true"/>
    <property name="lastName" column="last_name" type="string" length="15" not-null="true"/> 
    <property name="draftDate" column="draft_date" type="date"/>
    <property name="annualSalary" column="salary" type="float"/> 
    <property name="jerseyNumber" column="jersey_number" type="integer" length="2" not-null="true"/>
    <many-to-one name="team" class="example.Team" column="team_id"/>
  </class>
</hibernate-mapping>

Figure 1 - example.Player mapping document
매핑 문서들은 매우 명확하지만, 좀 더 설명이 필요한 부분이 있다.
id 요소는 퍼시스턴스 클래스에 의해서 사용되는 pk를 뜻하는 것으로 id 요소의 속성은 다음과 같다.

  • name: 퍼시스턴스 클래스에 의해서 사용되는 프로퍼티
  • column: 주요 키의 컬럼명
  • type: 자바 데이터 타입
  • unsaved-value: 이 값은 클래스가 데이터베이스에 저장이 되었는지 알기 위해서 사용된다.
만약 id 속성이 null이라면 하이버네이트는 이 객체가 저장이 안된 것으로 인식한다.
이 속성은 나중에 설명하게 될 saveOrUpdate() 메소드를 호출할 때 중요하다.

generator 요소는 주요 키를 생성하는데 사용되는 메소드를 명시한다.
여기서는 hilo generator가 사용되었지만, 하이버네이트 2.0 에서는 10여 가지 key generation 메소드를 제공한다.
그뿐만 아니라, 복합 pk를 포함하여 개발자 자신만의 메커니즘을 이용하는 것도 가능하다.


property 요소는 표준 자바 속성을 정의하고, 스키마에서 이것들이 컬럼으로 매핑되는 방법을 정의하게 된다.
속성은 컬럼의 길이, SQL 타입, 널 값 사용 가능 유무를 명시할 수 있다.
property에는 column이라는 child element를 제공한다. 이 element는 컬럼에 대한 인덱스 명이나 특정 컬럼 타입 같은 추가적인 특징을 명시하기 위해 사용된다.

Team 클래스는 추가적인 element 블록을 가지고 있다. 이것은 Team에 속한 Players의 컬렉션을 나타낸다.
<set name="players" cascade="all" inverse="true" lazy="true">
  <key column="team_id"/>
  <one-to-many class="example.Player"/>
</set>
Figure 2 - example.Team collection defintion

figure 3은 Player 클래스에 정의된 양방향 매핑을 사용하여 Team에 매핑되게 될 Players 셋을 정의한다.
그리고 이것은 스키마가 생성될 때 하이버네이트에 의해 만들어질 것이다.
키 요소는 (이 players 셋을) 소유하고 있는 클래스의 외래키를 사용하여 컬렉션의 인스턴스들을 구분해준다.
one-to-many element는 정의된 집합 안에 어떤 객체가 담겨 있는지 정의한다.
예를 들어, Players라는 컬렉션은 Team의 team_id라는 컬럼을 foreign key로 참조하며, 컬렉션 안에는 example.Player 객체를 담게 된다.

set 요소에 있는 lazy와 inverse라는 두 가지 속성에 주목해야 한다.
컬렉션을 lazy="true"라 표기하는 것은 컬렉션을 포함하는 객체를 데이터베이스로부터 얻어올 때, 컬렉션이 자동으로 생성되지 않는다는 것을 의미한다.
예를 들어, 데이터베이스로부터 Team 객체를 얻어온다면 Players 객체는 애플리케이션이 접근할 때까지 생성하지 않을 것이다.
Lazy 컬렉션 초기화는 성능에 대한 고려지점 section에서 더욱 상세하게 설명될 것이다.

inverse 속성은 Player 매핑문서에서 Player가 다음과 같이 Team에 속한다는 것을 결정지을 수 있다는 점에서 양방향성을 가진다는 것을 의미한다.
<many-to-one name="team" class="example.Team" column="team_id"/>
Figure 3 - bi-directional association from the Player class to the Team class

위의 라인은 Player가 그것에 연관된 Team 에 양방향으로 관련되어 있음을 나타내는 특징들을 보여준다.


하이버네이트 프라퍼티
#

하이버네이트가 데이터베이스와 접속하거나 스키마를 생성하기 위해서 사용하는 프로퍼티는 hibernate.properties에 작성된다.
우리의 목적을 위해서, 이 파일은 다섯개의 프라퍼티를 가진다. 하지만, 더 많은 것들도 가능하다.
hibernate.connection.username=ralph
hibernate.connection.password=nader
hibernate.connection.url=jdbc:postgresql://localhost/example
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.dialect=net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.connection.pool_size=# optional, see below
Figure 4 - example hibernate.properties

처음 4개의 프라퍼티 값은 JDBC로 작업을 해본 개발자라면 누구에게나 친근할 것이다.
마지막 프라퍼티인 hibernate.dialect는 하이버네이트에서 제공하는 Hibernate Query Language(HQL)을 SQL로 변환하고, 최초 사용을 위한 데이터베이스 스키마 생성을 위해 필요한 SQL dialect를 지정한다.
만약 우리가 이후에 PostgreSQL 대신에 오라클을 사용할 것을 선택하게 된다면, 우리는 간단히 사용하는 dialect를 변경하고 필요에 따라 커넥션 파라미터를 수정하기만 하면 된다.
HQL 문장은 MySQL에서 nested 셀렉트 문장이 지원되지 않는 것과 같이 사용할 데이터베이스에 유니크한 특징들에 따라 작성되어야 할 것이다.

데이터베이스를 개선할 추가적인 특징은 쿼리문장의 대체이다.
이러한 대체는 개발자들이 hibernate.query.substitutions 프라퍼티를 사용하여, SQL 함수 혹은 토큰들의 이름을 바꿀 수 있게 한다.
hibernate.query.substitutions toUpper=UPPER # rename the SQL UPPER() function to 'toUpper()'
Figure 5 - hibernate.query.substitutions

이 특징은 만약 당신의 데이터베이스에서 boolean TRUE, FALSE 값을 지원하지 않을 때 유용하다.
하이버네이트는 내부에 커넥션 풀을 가지고 있다. 하지만, 이것은 단지 테스트와 프레임워크 체험용에 적합한 것이다.
중요한 개발에 사용하기 위해서, 하이버네이트는 C3P0, 아파치 DBCP, 그리고 Proxool connection pools 를 지원한다.
이러한 유틸리티들에 대한 연계는 리소스 section 에서 제공한다.
만약, 당신이 선호하는 커넥션 풀링 프레임워크가 아직 지원되지 않는다면, 당신은 net.sf.hibernate.connection.ConnectionProvider 인터페이스를 임플레먼트 함으로써 추가시킬 수 있다.
당신은 또한 hibernate.show_sql 프라퍼티를 true로 세팅함으로써 하이버네이트로 하여금 콘솔에 생성된 SQL 문을 출력하도록 세팅할 수 있다.


스키마
#

우리는 매핑 파일들을 통해 데이터베이스 스키마를 생성할 수 있다.
하이버네이트는 매핑문서에 필요한 스키마를 생성해줄 SchemaExport 유틸리티를 가지고 있다.
이 유틸리티는 실행창 또는 Ant 빌드 스크립트로 실행되어, 데이터베이스에 연결하고 스키마를 생성하거나 스키마를 파일로 만든다.
# from the command line
java -cp classpath net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files

<!-- from an Ant build.xml -->
<target name="init-db">
  <taskdef classname="net.sf.hibernate.tool.hbm2ddl.SchemaExportTask"
      classpathref="project.class.path" name="schemaexport"/>
  <schemaexport delimiter=";" drop="false" output="schema.sql"
      properties="config/hibernate.properties" quiet="false" text="false">
    <fileset dir="${build.destdir}">
      <include name="**/*.hbm.xml"/>
    </fileset>
  </schemaexport>
</target>
Figure 6 - SchemaExport usage

우리 스키마는 아래와 같다.
Figure 7

Figure 7 - generated database schema

Hibernate_unique_key 테이블은 hilo 제네레이터 타입의 id 값으로 저장된다.


소스 파일들
#

나는 퍼시스턴스 클래스를 생성하기보다는, 하이버네이트 확장팩에 실려있는CodeGenerator를 사용할 것이다.
CodeGenerator는 위에서 설명된 매핑문서에 따라 우리 필요에 맞는 조각(stub) 파일들을 생성할 것이다.
(이 기사에서 제공되는 코드 묶음들은 리소스 section 에서 찾아볼 수 있다.)
CodeGenerator를 사용하는 것은 SchemaExport 유틸리티를 사용하는 것과 비슷하다.
java -cp classpath net.sf.hibernate.tool.hbm2java.CodeGenerator options mapping_files
Figure 8 - CodeGenerator usage

생성된 클래스들은 다음과 같은 구조를 가진다.(간결함을 위해 생성자는 다이어그램에서 제거되었다.)


Figure 9 - diagram of example classes generated by Hibernate


SessionFactory 생성하기
#

SessionFactory는 팩토리가 생성될 때 서술된 컴파일된 매핑문서를 저장한다.
SessionFactory를 생성하는 것은 꽤나 수월한 일이다. 모든 매핑들은 SessionFactory 객체를 생성할 때 사용되는 net.sf.hibernate.cfg.Configuration 객체에 추가된다.
Configuration cfg = new Configuration()
    .addClass(example.Player.class)
    .addClass(example.Team.class);
SessionFactory factory = cfg.buildSessionFactory();
Figure 10 - Configuring and creating a SessionFactory

Configuration 클래스는 SessionFactory 클래스의 생성에만 필요하다.그리고 팩토리가 생성된 이후에는 삭제된다.
Session의 인스턴스들은 SessionFactory.openSession() 메써드를 호출함으로써 얻어진다.
Session 인스턴스의 논리적인 라이프싸이클은 데이터베이스 트랜잭션의 기간 동안이다.

SessionFactory는 XML 매핑파일을 당신의 클래스패쓰의 root에 놓는 것으로도 역시 configure 될 수 있다.
이러한 방식이 가지는 좋은 이점은 당신의 configuration이 어플리케이션에 하드코딩되지 않아도 된다는 점이다.


퍼시스턴스 클래스 생성과 수정
#

하이버네이트가 관계되어 있는 한, 클래스들은 순간적(transient)이거나 영속적(persistent)이다.
transient 클래스들은 데이터베이스에 저장되지 않는 객체들이다.
transient 인스턴스를 영속적인 것으로 만들기 위해서는, 그것을 Session 클래스를 사용하여 간단하게 저장해주면 된다.
Player player = new Player();  // … populate player object
Session session = SessionFactory.openSession();
session.saveOrUpdate(player);
Figure 11 - saving persistent objects

saveOrUpdate(Object) 호출은 만일 id 프라퍼티가 null이라면, 데이터베이스에 SQL INSERT를 불러냄으로써 객체를 저장한다.
이것은 우리가 Player 매핑문서에서 정의한 unsaved-value 속성을 참조한다.
만약 id가 null이 아니라면, saveOrUpdate(Object) 호출은 update를 발생시킬 것이고, SQL UPDATE 작용이 데이터베이스에 일어날 것이다.
(이 토픽에 대한 좀 더 상세한 정보는 아래에 있는 unsaved-Value Strategies 라는 부가설명을 참조하길 바란다.)

Playes가 배정된 Team을 생성하고 저장하기 위해서, 객체를 생성하고 이것을Session 인스턴스를 이용해 저장하는 것과 똑 같은 방식을 따라하면 된다.
Team team = new Team();
team.setCity("Detroit");
team.setName("Pistons");

// add a player to the team.
Player player = new Player();
player.setFirstName("Chauncey");
player.setLastName("Billups");
player.setJerseyNumber(1)
player.setAnnualSalary(4000000f);
Set players = new HashSet();
players.add(player);
team.setPlayers(players);

// open a session and save the team
Session session = SessionFactory.openSession();
session.saveOrUpdate(team);
Figure 12 - persisting objects

이것은 Team 인스턴스와 Set 객체 안에 들어있는 각각의 Player 인스턴스들을 영속적이게 만들어 줄 것이다.
Unsaved Value Strategies
id 요소에 의해 지원되는 Unsaved-value 속성은 객체가 새롭게 생성되었으며, 
일시적인 것인지, 아니면 이 객체가 이미 저장된 것인 것인지를 지시해준다.
디폴트 값은 null 이며 이것은 대부분의 경우에 충분하다.
그러나, 만약 당신의 indentifier 프라퍼티가 null로 디폴트 값을 주지 않았을 경우, 당신은 반드시 
transient(새롭게 생성된객체를 위해 디폴트 값을 부여해줘야만 한다.
unsaved-value 속성에 의해 지원되는 다른 값들은 any, none 그리고 id-value 이다.


퍼시스턴트 클래스들을 가져오기
#

만약 당신이 당신이 추출하기를 바라는 객체의 pk 값을 알고 있다면, 당신은 Session.load() 메써드를 통해 값을 가져올 수 있다.
이 메써드는 기본적인 클래스들과 BMP 엔티티빈즈에 대한 지원을 제공한다.
// method 1: loading a persistent instance 
Session session = SessionFactory.createSession();
Player player = session.load(Player.class, playerId);

// method 2: loading the Player&apos;s state
Player player = new Player();
session.load(player, playerId);
Figure 13 - Loading persistent instances

pk 값을 모른채 퍼시스턴트 클래스를 추출하기 위해서는, 당신은 Session.find() 메써드를 사용할 수 있다.
find() 메써드는 당신이 HQL(Hibernate Query Language) 문장을 넘겨주면, 매치되는 객체들을 java.util.List 타입의 객체로 반환해준다.
find() 메써드는 3개의 signatures를 가지는데, 이것은 당신으로 하여금, JDBC-like “?” 파라미터를 단일 아규먼트, named 파라미터들 혹은 Object 형태로 넘겨줄 수 있게끔 한다.
(HQL에 대한 좀 더 많은 정보는 Hibernate Query Language에 관련한 추가설명을 참조하길 바란다.)
Hibernate Query Language
HQL에서 사용되는 질의문들은 그들의 SQL 대응부분들만큼이나 강력하다.
inner 및 outer 조인이 지원되고, avg(), sum(), min(그리고 count(등과 같은 다양한 함수들 역시 지원된다.
HQL은 또한 distinct 와 like 와 같은 여러가지 SQL 비슷한 함수 및 명령들 역시 지원한다.
만약 기반하고 있는 데이터베이스에 의해 지원된다면, 서브쿼리들 역시 지원되며, group by 절 역시 마찬가지이다.
named 파라미터들은, 파라미터 플래그로 물음표를 사용하는 대신에, HQL 문장에서 당신이 이름을 쓸 수 있게 한다.
예를 들어,

select team.id from team in class example.Team where team.name=:name
:name 파라미터의 값을 세팅해주기 위해서는 Query.setParameter(메써드를 사용하면 된다.
앞서 기술한 바와 같이, 그것은 아래와 같은 형태가 될 것이다.

query.setParameter("name""Pistons", Hibernate.STRING);

HQL은 매우 훌륭한 객체 질의문이며 깊이 있기 때문에, 이후에도 계속 다루어질 것이다.


퍼시스턴트 클래스들 삭제하기
#

퍼시스턴트 객체를 트랜젼트로 만드는 것은 Session.delete() 메써드로 할 수 있다.
이 메써드는 삭제하기 위해 특정한 객체를 넘겨주거나 데이터베이스로부터 복수의 객체들을 삭제하기 위해 질의문을 넘겨줄 수 있다.
// method 1 - deleting the Player loaded in figure 12
session.delete(player);
  
// method 2 - deleting all of the Players with a
// salary greater than 4 million
session.delete("from player in class example.Player where player.annualSalary > 4000000");
Figure 14 - deleting a persistent object

객체가 데이터베이스로부터 지워졌다고 하더라도, 당신의 어플리케이션에서는 여전히 그 객체에 대한 참조를 하고 있다는 사실은 주목해야 한다.
Team 객체가 가지고 있는 Player 객체들의 Set과 같이, 객체의 컬렉션들을 가진 객체를 삭제하는 것은 매핑문서의 set 요소에서 cascade=”delete” 라고 서술해줌으로써 자식 객체들까지 연계시킬 수 있다.


컬렉션들
#

하이버네이트는 객체 컬렉션들,그것이 Sets이건 Maps이건 객체나 기본타입 값들의 배열이건 간에,의 퍼시스턴스도 관리할 수 있다.
하이버네이트는 “bag”이라 불리는 또다른 컬렉션의 형태도 허용한다.
bag은, 객체들의 정렬되지 않고, 색인되지 않은 컬렉션인, Collection 혹은 List 로 매핑가능하다.
Bags는 같은 요소를 수차례 저장할 수 있다.

LinkedList 와 같이, 다른 클래스들을 구현한 부가적인 클래스들은 저장시 유지되지 않는다.
(원문 : Additional semantics supported by implementing classes, such as LinkedList, are not maintained when persisted.)

또 다른 주의사항은 컬렉션의 프라퍼티는 (List, Map, Set과 같이) 인터페이스 타입이어야만 한다는 점이다.
lazy 컬렉션을 지원하기 위해, 하이버네이트는 List, Map 혹은 Set 인터페이스를 구현한 자체적인 구현 클래스들을 사용하고 있기 때문이다.
늦은 초기화 컬렉션에 접근할 때, Session은 반드시 열려 있어야 한다는 사실을 명심해야만 한다. 그렇지 않다면 익셉션이 발생할 것이다.
Session session = factory.openSession();
Team team = (Teamsession.find("from team in class example.Team where team.city = ?"
                                cityName, Hibernate.STRING).get(0);
Set players = team.getPlayers();
session.close();
Player p = (Playerplayers.get(0)// exception will be thrown here
Figure 15 - incorrect use of lazy initialization

Figure 15 에서 Players를 저장하기 위해 필요한 Session이 너무 빨리 닫혀버렸기 때문에, 익셉션이 발생하였다.
이런 버그의 가능성 때문에, 하이버네이트는 non-lazy collections를 디폴트로 하고 있다.
그러나, lazy 컬렉션들은 성능향상을 목적으로 사용될 수 있다.


성능에 대한 고려지점
#

다행스럽게도 이러한 기능성은 실행비용의 그다지 큰 부분은 아니다.
하이버네이트 웹사이트는 “JDBC 호출의 10%의 오버헤드도 발생되지 않는다.”고 주장한다.
그리고 하이버네이트를 사용한 나의 어플리케이션 개발경험에서도 이것은 증명된다.
필요할 경우 하이버네이트는, (데이터베이스와의 상호작용, 객체들의 캐쉬, 효율적인 아우터조인 fetching과 SQL 문장의 실행 등) 복수의 최적화를 할 수 있다.
손으로 코딩한 JDBC로 이러한 수준의 주장을 달성하기란 어려운 일이다.

하이버네이트 웹사이트에서 퍼포먼스 FAQ에 대한 링크는 리소스 section에서 찾아볼 수 있다.


Persistence 클래스 대체안
#

OJB: OJB(ObjectRelationalBridge)는 관계형 데이터베이스에 대응하는 자바 객체를 위한 명쾌한 퍼시스턴스를 허용하는 객체/관계 매핑 툴이다. 아파치 라이센스이다. http://db.apache.org/ojb/
Castor: Castor는 자바 애플리케이션을 위한 오픈 소스 데이터 바인딩 프레임워크이다. http://castor.exolab.org
CocoBase: CocoBase는 J2EE, J2SE, J2ME 플랫폼에 기반한 자바 개발자를 위한 사용하기 단순하면서, 강력한 Dynamic Object to Relational Mapping 툴을 제공한다. 상용이다. http://www.thoughtinc.com/cber_index.html
TopLink: TopLink를 통해, 개발자는 자바 객체와 엔티티빈 모두 관계형 데이터베이스 스키마에 매핑할 수 있다. 최근 TopLink는 오라클에 인수되었다. 상용이다. http://www.oracle.com/features/9iAS/index.html?t1as_toplink.html


결론
#

본 기사에서는 하이버네이트가 할 수 있는 것들에 대해 소개 정도만 제공했다. 하지만, 하이버네이트는 높은 성능을 제공할 뿐만 아니라 다른 오픈 소스나 상용 제품들과 비교해보았을 때에도 결코 뒤지지 않은 오픈 소스 퍼시스턴스 프레임워크를 제공한다. 하이버네이트를 사용하는 개발자들은 시간, 노력, 필요한 코드, 테스트의 양을 엄청나게 줄일 수 있으며, 어플리케이션을 배치할 수 있다. 그러나, 우리는 단지 표면만을 긁어보았을 뿐이고, 나는 당신이 하이버네이트를 당신 스스로 탐험해보기를 바란다.


저자에 대해
#

닉 휴데커는 엔터프라이즈 어플리케이션에 대한 설계와 개발 경험을 8년 넘게 가진 소프트웨어 개발자이다. 그의 회사, System Mobile, Inc. 는 어플리케이션 통합, 소프트웨어 개발, 무선 어플리케이션을 특화로 하고 있다. 그는 썬 공인 자바 프로그래머(Sun Certified Java Programmer)이며, 현재 시카고에 살고 있다.


리소스
#

The example source code and mapping documents can be found at: http://www.systemmobile.com/articles/hibernate.zip
Hibernate website: http://www.hibernate.org/
Hibernate performance FAQ: http://www.hibernate.org/15.html
Hibernate feature list: http://www.hibernate.org/4.html
A comparison of various ORM frameworks: http://c2.com/cgi-bin/wiki?ObjectRelationalToolComparison
C3P0 Connection Pooling
Apache DBCP Pooling
Proxool Connection Pooling
The System Mobile website: http://www.systemmobile.com/

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
jpg
figure7.jpg 18.8 kB 1 06-Apr-2006 09:45 211.41.109.42
jpg
figure8.jpg 45.7 kB 1 06-Apr-2006 09:45 211.41.109.42
« This page (revision-1) was last changed on 06-Apr-2006 09:45 by UnknownAuthor