개발 환경 및 종속성 준비
Java 기반 프로젝트에서 Hibernate ORM을 활성화하려면 필수 라이브러리를 클래스패스에 등록해야 합니다. 본 예제에서는 Microsoft SQL Server를 데이터소스로 활용하므로 sqljdbc4.jar 또는 호환되는 Microsoft JDBC 드라이버를 포함해야 합니다. 프로젝트 패키지 구조는 도메인 모델, 매핑 설정, 실행 진입점을 분리하는 계층형으로 구성됩니다.
1. XML 기반 매핑 구현
전통적인 XML 매핑 방식은 도메인 객체와 관계형 테이블 간의 연결 규약을 별도 파일로 분리하여 관리합니다. 이 방법은 런타임 리플렉션에 대한 의존도를 낮추고 설정 변경 시 코드 재컴파일을 피할 수 있는 장점이 있습니다.
도메인 모델 정의
데이터베이스 테이블 컬럼과 일대일로 대응하는 자바 빈(POJO)을 작성합니다. 별도의 프레임워크 어노테이션 없이 순수 getter/setter 구조로 구성됩니다.
package com.demo.model;
public class Trainee {
private Integer traineeId;
private String fullName;
private int experienceYears;
public Trainee() {}
public Trainee(Integer traineeId, String fullName, int experienceYears) {
this.traineeId = traineeId;
this.fullName = fullName;
this.experienceYears = experienceYears;
}
public Integer getTraineeId() { return traineeId; }
public void setTraineeId(Integer traineeId) { this.traineeId = traineeId; }
public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }
public int getExperienceYears() { return experienceYears; }
public void setExperienceYears(int experienceYears) { this.experienceYears = experienceYears; }
}
관계형 매핑 파일 작성
Trainee.hbm.xml 파일을 통해 클래스와 테이블, 속성과 컬럼의 대응 관계를 선언합니다. 생성기 전략은 데이터베이스 방언에 맞게 native로 설정합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.demo.model.Trainee" table="tbl_trainee">
<meta attribute="class-description">교육 프로그램 참석자 정보 테이블</meta>
<id name="traineeId" column="id" type="java.lang.Integer">
<generator class="native"/>
</id>
<property name="fullName" column="name" type="java.lang.String"/>
<property name="experienceYears" column="exp_years" type="java.lang.Integer"/>
</class>
</hibernate-mapping>
핵심 설정 및 실행 진입점
hibernate.cfg.xml에서 JDBC 연결 정보, SQL 방언, DDL 자동 생성 전략을 정의하고 앞서 작성한 매핑 파일을 로드합니다. 실행 클래스는 세션 팩토리를 초기화한 후 트랜잭션 내에서 영속성 컨텍스트를 통해 데이터를 저장합니다.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://localhost:1433;databaseName=training_db</property>
<property name="connection.username">db_admin</property>
<property name="connection.password">secure_pass_456</property>
<property name="connection.pool_size">5</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/demo/model/Trainee.hbm.xml" />
</session-factory>
</hibernate-configuration>
package com.demo.app;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.demo.model.Trainee;
public class PersistenceRunner {
public static void main(String[] args) {
Configuration hibernateConfig = new Configuration().configure();
SessionFactory sessionFactory = hibernateConfig.buildSessionFactory();
Session dbSession = sessionFactory.openSession();
try {
dbSession.beginTransaction();
Trainee newRecord = new Trainee();
newRecord.setFullName("김민수");
newRecord.setExperienceYears(5);
dbSession.save(newRecord);
dbSession.getTransaction().commit();
} catch (Exception ex) {
ex.printStackTrace();
if (dbSession.getTransaction() != null) {
dbSession.getTransaction().rollback();
}
} finally {
if (dbSession != null && dbSession.isOpen()) {
dbSession.close();
}
}
}
}
2. 어노테이션 기반 매핑 구현
Java 5 이상에서 도입된 표준 어노테이션을 활용하면 매핑 메타데이터를 클래스 내부에 직접 선언할 수 있습니다. 별도의 XML 매핑 파일이 필요 없어 프로젝트 구조가 단순해지며, IDE 코드 완성도와 컴파일 시 타입 안정성이 향상됩니다.
매핑 정보가 포함된 엔티티 클래스
JPA 스펙 어노테이션(@Entity, @Table, @Id, @Column 등)을 적용하여 도메인 객체를 영속성 관점의 엔티티로 전환합니다.
package com.demo.model;
import javax.persistence.*;
@Entity
@Table(name = "tbl_trainee")
public class Trainee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer traineeId;
@Column(name = "name", nullable = false)
private String fullName;
@Column(name = "exp_years")
private int experienceYears;
public Trainee() {}
public Trainee(Integer traineeId, String fullName, int experienceYears) {
this.traineeId = traineeId;
this.fullName = fullName;
this.experienceYears = experienceYears;
}
public Integer getTraineeId() { return traineeId; }
public void setTraineeId(Integer traineeId) { this.traineeId = traineeId; }
public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }
public int getExperienceYears() { return experienceYears; }
public void setExperienceYears(int experienceYears) { this.experienceYears = experienceYears; }
}
설정 파일 조정 및 동일 실행 구조
hibernate.cfg.xml의 매핑 등록 부분을 <mapping resource="..." />에서 <mapping class="..." />으로 변경하여 어노테이션 스캐닝을 활성화합니다. 실행 로직은 XML 방식과 완전히 동일하게 동작합니다.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://localhost:1433;databaseName=training_db</property>
<property name="connection.username">db_admin</property>
<property name="connection.password">secure_pass_456</property>
<property name="connection.pool_size">5</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- XML 매핑 대신 클래스 기반 어노테이션 매핑 활성화 -->
<mapping class="com.demo.model.Trainee" />
</session-factory>
</hibernate-configuration>
실행 진입점인 PersistenceRunner 클래스는 앞서 XML 방식에서 작성한 코드와 동일하게 구성됩니다. Hibernate는 설정 파일에서 클래스 기반 매핑을 감지하면 리플렉션을 통해 어노테이션을 파싱하고 메타데이터 모델을 자동으로 생성합니다.