초보자를 위한 Hibernate 튜토리얼에 오신 것을 환영합니다. Hibernate은 가장 널리 사용되는 Java ORM 도구 중 하나입니다. 대부분의 응용 프로그램은 응용 프로그램 정보를 저장하기 위해 관계형 데이터베이스를 사용하며, 낮은 수준에서는 JDBC API를 사용하여 데이터베이스에 연결하고 CRUD 작업을 수행합니다.
초보자를 위한 Hibernate 튜토리얼
JDBC 코드를 살펴보면 많은 보일러플레이트 코드가 있으며, 자원 누수와 데이터 일관성 문제가 발생할 수 있습니다. 이는 모든 작업을 개발자가 수행해야하기 때문에 번거롭습니다. 이런 경우 ORM 도구가 유용합니다. 객체-관계 매핑(ORM)은 응용 프로그램 도메인 모델 개체를 관계형 데이터베이스 테이블에 매핑하는 프로그래밍 기술입니다. Hibernate은 자바 기반의 ORM 도구로, 응용 프로그램 도메인 개체를 관계형 데이터베이스 테이블에 매핑하고 그 반대로 수행하는 프레임워크를 제공합니다. Hibernate를 ORM 도구로 사용하는 장점 중 일부는 다음과 같습니다:
- Hibernate는 자바 클래스를 데이터베이스 테이블과 그 반대로 매핑할 수 있습니다. 주요 관계형 데이터베이스 전체에서 CRUD 작업을 수행하는 기능을 제공합니다.
- 하이버네이트는 JDBC와 함께 제공되는 번거로운 코드를 제거하고 리소스 관리를 처리하여 데이터베이스 작업이 리소스 누수를 발생시키지 않는지 확인하는 대신 비즈니스 사용 사례에 집중할 수 있도록 도와줍니다.
- 하이버네이트는 트랜잭션 관리를 지원하고 시스템에서 일관되지 않은 데이터가 없도록 보장합니다.
- XML, 속성 파일 또는 주석을 사용하여 자바 클래스를 데이터베이스 테이블에 매핑하기 때문에 응용 프로그램과 데이터베이스 사이에 추상화 계층을 제공합니다.
- 하이버네이트는 조인, 컬렉션, 상속 객체의 매핑을 지원하며, 모델 클래스가 데이터베이스 테이블을 어떻게 나타내는지 쉽게 시각화할 수 있습니다.
- 하이버네이트는 SQL과 유사한 강력한 쿼리 언어(HQL)를 제공합니다. 그러나 HQL은 완전히 객체 지향적이며 상속, 다형성 및 연관성과 같은 개념을 이해합니다.
- 하이버네이트는 몇 가지 외부 모듈과 통합 기능을 제공합니다. 예를 들어 하이버네이트 Validator는 Bean Validation (JSR 303)의 참조 구현체입니다.
- 하이버네이트는 레드햇 커뮤니티의 오픈 소스 프로젝트로 전 세계적으로 사용되고 있습니다. 이로 인해 학습 곡선이 작고 온라인 문서와 포럼에서 쉽게 도움을 받을 수 있기 때문에 다른 것보다 더 좋은 선택입니다.
- 하이버네이트는 다른 Java EE 프레임워크와 쉽게 통합할 수 있으며, Spring Framework은 하이버네이트를 Spring 애플리케이션과 통합하기 위한 내장 지원을 제공합니다.
I hope all the above benefits will convince you that Hibernate is the best choice for your application object-relational mapping requirements. Let’s look at the Hibernate Framework architecture now and then we will jump into sample project where we will look into different ways to configure Hibernate in standalone java application and use it.
Hibernate 아키텍처
아래 이미지는 Hibernate 아키텍처를 보여주며, 애플리케이션 클래스와 데이터베이스 작업을 위한 JDBC/JTA API 사이의 추상화 계층으로 작동하는 방식을 보여줍니다. Hibernate는 JDBC와 JTA API 위에 구축되어 있음을 알 수 있습니다. 이제 Hibernate 아키텍처의 핵심 구성 요소를 하나씩 살펴보겠습니다.
- SessionFactory (org.hibernate.SessionFactory): SessionFactory는 단일 데이터베이스에 대한 컴파일된 매핑의 불변적이고 스레드 안전한 캐시입니다.
org.hibernate.SessionFactory
의 인스턴스를 사용하여org.hibernate.Session
을 얻을 수 있습니다. - Session (org.hibernate.Session): Session은 애플리케이션과 영구 저장소 간의 대화를 나타내는 단일 스레드, 단기간 객체입니다. JDBC
java.sql.Connection
을 래핑하고org.hibernate.Transaction
의 팩토리로 작동합니다. - 지속적인 객체: 지속적인 객체는 단기간, 단일 스레드 객체로서 지속 상태와 비즈니스 기능을 포함합니다. 이들은 일반적인 JavaBeans/POJO일 수 있습니다. 이들은 정확히 하나의
org.hibernate.Session
에 연결됩니다. - 일시적인 객체: 일시적인 객체는 현재
org.hibernate.Session
과 연관되지 않은 영속 클래스의 인스턴스입니다. 이들은 응용 프로그램에 의해 생성되고 아직 영속화되지 않았을 수도 있으며, 또는 닫힌org.hibernate.Session
에 의해 생성될 수도 있습니다. - 트랜잭션 (org.hibernate.Transaction): 트랜잭션은 응용 프로그램에서 원자적인 작업 단위를 지정하는 데 사용되는 단일 스레드, 단기간 객체입니다. 이는 응용 프로그램을 기본 JDBC 또는 JTA 트랜잭션으로부터 추상화합니다. 경우에 따라서는
org.hibernate.Session
이 여러org.hibernate.Transaction
을 포함할 수 있습니다. - ConnectionProvider (org.hibernate.connection.ConnectionProvider): ConnectionProvider는 JDBC 연결을 위한 팩토리입니다. 이는 응용 프로그램과 기본
javax.sql.DataSource
또는java.sql.DriverManager
간의 추상화를 제공합니다. 응용 프로그램에 노출되지는 않지만 개발자에 의해 확장될 수 있습니다. - TransactionFactory (org.hibernate.TransactionFactory):
org.hibernate.Transaction
인스턴스를 위한 팩토리입니다.
Hibernate와 Java Persistence API (JPA)
하이버네이트는 Java Persistence API의 구현을 제공하므로 JPA 주석을 모델 빈과 함께 사용할 수 있으며 하이버네이트가 CRUD 작업에 대한 구성을 처리합니다. 주석 예제로 살펴보겠습니다.
하이버네이트 예제
하이버네이트 애플리케이션을 개발할 때는 두 가지 구성을 제공해야 합니다. 첫 번째 구성 세트에는 데이터베이스에 대한 구체적인 속성이 포함되어 있으며 이는 데이터베이스 연결 및 세션 객체 생성에 사용됩니다. 두 번째 구성 세트에는 모델 클래스와 데이터베이스 테이블 간의 매핑이 포함됩니다. 데이터베이스 연결 관련 구성에는 XML 기반 또는 속성 기반 구성을 사용할 수 있습니다. 모델 클래스와 데이터베이스 테이블 매핑을 위해 XML 또는 주석 기반 구성을 사용할 수 있습니다. 주석 기반 매핑을 위해 javax.persistence
의 JPA 주석을 사용할 것입니다. 최종 프로젝트는 아래 이미지와 같습니다. Eclipse 또는 사용하는 IDE에서 Maven 프로젝트를 생성하고 원하는 이름을 사용할 수 있습니다. 프로젝트의 다른 구성 요소로 이동하기 전에 데이터베이스 설정을 수행해야 합니다.
데이터베이스 테이블 설정
예시로 MySQL 데이터베이스를 사용하며, 아래 스크립트는 필요한 테이블을 생성하는 데 사용됩니다.
CREATE TABLE `Employee` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`role` varchar(20) DEFAULT NULL,
`insert_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
Employee 테이블의 “id” 열은 MySQL에 의해 자동으로 생성되므로 삽입할 필요가 없습니다.
Hibernate 프로젝트 종속성
최종 pom.xml 파일은 다음과 같습니다.
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.hibernate</groupId>
<artifactId>HibernateExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HibernateExample</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>
<!-- Hibernate 4 uses Jboss logging, but older versions slf4j for logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
hibernate-core 아티팩트에는 모든 핵심 하이버네이트 클래스가 포함되어 있으므로 프로젝트에 필요한 모든 기능을 얻을 수 있습니다. 제 샘플 프로젝트에서는 최신 하이버네이트 버전(4.3.5.Final)을 사용하고 있으며, 하이버네이트는 여전히 발전 중인 상태입니다. 각 주요 릴리스마다 핵심 클래스가 많이 변경되는 것을 확인했습니다. 따라서 다른 버전을 사용하는 경우에는 작동하도록 하이버네이트 구성을 수정해야 할 수도 있습니다. 그러나 4.x.x 릴리스에 대해서는 문제없이 작동할 것입니다. Hibernate 4는 JBoss 로깅을 사용하지만 이전 버전에서는 로깅 용도로 slf4j를 사용하므로 프로젝트에 slf4j-simple 아티팩트를 포함했습니다. 이는 필요하지 않지만 Hibernate 4를 사용하고 있기 때문입니다. mysql-connector-java는 MySQL 데이터베이스에 연결하기 위한 MySQL 드라이버입니다. 다른 데이터베이스를 사용하는 경우 해당 드라이버 아티팩트를 추가하십시오.
도메인 모델 클래스
위 이미지에서 보시는 대로, 우리는 두 개의 모델 클래스인 Employee
와 Employee1
을 가지고 있습니다. Employee는 간단한 자바 빈 클래스이며, XML 기반의 구성을 사용하여 매핑 세부 정보를 제공할 것입니다. Employee1은 필드가 JPA 주석으로 주석 처리된 자바 빈으로, 별도의 XML 파일에서 매핑을 제공할 필요가 없습니다.
package com.journaldev.hibernate.model;
import java.util.Date;
public class Employee {
private int id;
private String name;
private String role;
private Date insertTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Date getInsertTime() {
return insertTime;
}
public void setInsertTime(Date insertTime) {
this.insertTime = insertTime;
}
}
Employee 클래스는 간단한 자바 빈입니다. 여기에 특별히 논의할 내용은 없습니다.
package com.journaldev.hibernate.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name="Employee",
uniqueConstraints={@UniqueConstraint(columnNames={"ID"})})
public class Employee1 {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID", nullable=false, unique=true, length=11)
private int id;
@Column(name="NAME", length=20, nullable=true)
private String name;
@Column(name="ROLE", length=20, nullable=true)
private String role;
@Column(name="insert_time", nullable=true)
private Date insertTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Date getInsertTime() {
return insertTime;
}
public void setInsertTime(Date insertTime) {
this.insertTime = insertTime;
}
}
javax.persistence.Entity
주석은 클래스를 엔티티 빈으로 표시하여 하이버네이트에 의해 영속화될 수 있도록 합니다. 하이버네이트는 JPA 구현을 제공하기 때문입니다. javax.persistence.Table
주석은 테이블 매핑과 열의 고유 제약 조건을 정의하는 데 사용됩니다. javax.persistence.Id
주석은 테이블의 기본 키를 정의하는 데 사용됩니다. javax.persistence.GeneratedValue
는 필드가 자동으로 생성될 것임을 정의하고 GenerationType.IDENTITY 전략을 사용하여 생성된 “id” 값이 빈에 매핑되고 자바 프로그램에서 검색될 수 있도록 합니다. javax.persistence.Column
은 필드를 테이블 열과 매핑하는 데 사용됩니다. 빈 속성에 대해 길이, null 허용 여부 및 고유성을 지정할 수도 있습니다.
Hibernate 매핑 XML 구성
위에서 언급한대로, Employee 클래스 매핑에는 XML 기반 구성을 사용할 것입니다. 이름은 어떤 것이든 선택할 수 있지만, 가독성을 위해 테이블 또는 자바 빈 이름을 선택하는 것이 좋습니다. Employee 빈에 대한 하이버네이트 매핑 파일은 다음과 같습니다. employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.journaldev.hibernate.model.Employee" table="EMPLOYEE">
<id name="id" type="int">
<column name="ID" />
<generator class="increment" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="role" type="java.lang.String">
<column name="ROLE" />
</property>
<property name="insertTime" type="timestamp">
<column name="insert_time" />
</property>
</class>
</hibernate-mapping>
XML 구성은 간단하며 주석 기반 구성과 동일한 작업을 수행합니다.
하이버네이트 구성 파일
XML 기반 구성과 주석 기반 구성을 위해 두 개의 하이버네이트 구성 XML 파일을 생성할 것입니다. hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.username">pankaj</property>
<property name="hibernate.connection.password">pankaj123</property>
<!-- Connection Pool Size -->
<property name="hibernate.connection.pool_size">1</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Outputs the SQL queries, should be disabled in Production -->
<property name="hibernate.show_sql">true</property>
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- mapping file, we can use Bean annotations too -->
<mapping resource="employee.hbm.xml" />
</session-factory>
</hibernate-configuration>
대부분의 속성은 데이터베이스 구성과 관련되어 있으며, 다른 속성의 세부 정보는 주석으로 제공됩니다. 하이버네이트 매핑 파일에 대한 구성을 주목하십시오. 여러 하이버네이트 매핑 파일을 정의하고 여기에서 구성할 수 있습니다. 또한 매핑은 세션 팩토리에 특정합니다. hibernate-annotation.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.username">pankaj</property>
<property name="hibernate.connection.password">pankaj123</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Mapping with model class containing annotations -->
<mapping class="com.journaldev.hibernate.model.Employee1"/>
</session-factory>
</hibernate-configuration>
대부분의 구성은 XML 기반 구성과 동일하지만, 차이점은 매핑 구성입니다. 클래스 및 패키지에 대한 매핑 구성을 제공할 수 있습니다.
Hibernate SessionFactory
I have created a utility class where I am creating SessionFactory
from XML based configuration as well as property based configuration. For property based configuration, we could have a property file and read it in the class, but for simplicity I am creating Properties instance in the class itself.
package com.journaldev.hibernate.util;
import java.util.Properties;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import com.journaldev.hibernate.model.Employee1;
public class HibernateUtil {
//XML 기반 구성
private static SessionFactory sessionFactory;
//Annotation 기반 구성
private static SessionFactory sessionAnnotationFactory;
//속성 기반 구성
private static SessionFactory sessionJavaConfigFactory;
private static SessionFactory buildSessionFactory() {
try {
// hibernate.cfg.xml에서 SessionFactory 생성
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
//예외를 기록하도록 해야 함
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
private static SessionFactory buildSessionAnnotationFactory() {
try {
// hibernate.cfg.xml에서 SessionFactory 생성
Configuration configuration = new Configuration();
configuration.configure("hibernate-annotation.cfg.xml");
System.out.println("Hibernate Annotation Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Annotation serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
//예외를 기록하도록 해야 함
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
private static SessionFactory buildSessionJavaConfigFactory() {
try {
Configuration configuration = new Configuration();
//속성 생성, 속성 파일에서도 읽을 수 있음
Properties props = new Properties();
props.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
props.put("hibernate.connection.url", "jdbc:mysql://localhost/TestDB");
props.put("hibernate.connection.username", "pankaj");
props.put("hibernate.connection.password", "pankaj123");
props.put("hibernate.current_session_context_class", "thread");
configuration.setProperties(props);
//매핑 파일 또는 어노테이션으로 클래스 설정 가능
//addClass(Employee1.class)는 리소스를 찾음
// com/journaldev/hibernate/model/Employee1.hbm.xml (좋지 않음)
configuration.addAnnotatedClass(Employee1.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Java Config serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
public static SessionFactory getSessionAnnotationFactory() {
if(sessionAnnotationFactory == null) sessionAnnotationFactory = buildSessionAnnotationFactory();
return sessionAnnotationFactory;
}
public static SessionFactory getSessionJavaConfigFactory() {
if(sessionJavaConfigFactory == null) sessionJavaConfigFactory = buildSessionJavaConfigFactory();
return sessionJavaConfigFactory;
}
}
XML 기반 또는 어노테이션 기반 매핑이든 SessionFactory를 만드는 방법은 동일합니다. 속성 기반의 경우, 속성을 Configuration 객체에 설정하고 SessionFactory를 만들기 전에 어노테이션 클래스를 추가해야 합니다. 전체적으로 SessionFactory를 만드는 과정은 다음 단계를 포함합니다:
- Configuration 객체 생성 및 구성
- ServiceRegistry 객체 생성 및 구성 설정 적용
configuration.buildSessionFactory()
를 사용하여 ServiceRegistry 객체를 인수로 전달하여 SessionFactory 객체를 가져옵니다.
우리 애플리케이션은 이제 거의 완성되었습니다. 몇 가지 테스트 프로그램을 작성하고 실행해보겠습니다.
Hibernate XML 구성 테스트
테스트 프로그램은 아래와 같습니다.
package com.journaldev.hibernate.main;
import java.util.Date;
import org.hibernate.Session;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateMain {
public static void main(String[] args) {
Employee emp = new Employee();
emp.setName("Pankaj");
emp.setRole("CEO");
emp.setInsertTime(new Date());
//세션 가져오기
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
//트랜잭션 시작
session.beginTransaction();
//모델 객체 저장
session.save(emp);
//트랜잭션 커밋
session.getTransaction().commit();
System.out.println("Employee ID="+emp.getId());
//세션 팩토리 종료, 그렇지 않으면 프로그램이 종료되지 않음
HibernateUtil.getSessionFactory().close();
}
}
프로그램은 자명한 내용이며, 테스트 프로그램을 실행하면 다음과 같은 출력을 얻습니다.
May 06, 2014 12:40:06 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:40:06 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:40:06 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:40:06 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 06, 2014 12:40:06 AM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
May 06, 2014 12:40:06 AM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate.cfg.xml
May 06, 2014 12:40:07 AM org.hibernate.cfg.Configuration addResource
INFO: HHH000221: Reading mappings from resource: employee.hbm.xml
May 06, 2014 12:40:08 AM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Hibernate Configuration loaded
Hibernate serviceRegistry created
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=pankaj, password=****}
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
May 06, 2014 12:40:08 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:40:08 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:40:08 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select max(ID) from EMPLOYEE
Hibernate: insert into EMPLOYEE (NAME, ROLE, insert_time, ID) values (?, ?, ?, ?)
Employee ID=19
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]
주목할 점은 생성된 직원 ID가 인쇄된다는 것입니다. 확인하기 위해 데이터베이스 테이블을 확인할 수 있습니다.
Hibernate 주석 구성 테스트
package com.journaldev.hibernate.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.journaldev.hibernate.model.Employee1;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateAnnotationMain {
public static void main(String[] args) {
Employee1 emp = new Employee1();
emp.setName("David");
emp.setRole("Developer");
emp.setInsertTime(new Date());
//세션 가져오기
SessionFactory sessionFactory = HibernateUtil.getSessionAnnotationFactory();
Session session = sessionFactory.getCurrentSession();
//트랜잭션 시작
session.beginTransaction();
//모델 객체 저장
session.save(emp);
//트랜잭션 커밋
session.getTransaction().commit();
System.out.println("Employee ID="+emp.getId());
//세션 팩토리 종료, 그렇지 않으면 프로그램이 종료되지 않음
sessionFactory.close();
}
}
위의 프로그램을 실행하면 다음과 같은 출력을 얻습니다.
May 06, 2014 12:42:22 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:42:22 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:42:22 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:42:22 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 06, 2014 12:42:22 AM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate-annotation.cfg.xml
May 06, 2014 12:42:22 AM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate-annotation.cfg.xml
May 06, 2014 12:42:23 AM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Hibernate Annotation Configuration loaded
Hibernate Annotation serviceRegistry created
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=pankaj, password=****}
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 06, 2014 12:42:23 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:42:23 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:42:23 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Employee ID=20
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]
XML 기반 구성과의 출력을 비교해보면 몇 가지 차이점을 알 수 있습니다. 예를 들어, 주석 기반 구성에서는 연결 풀 크기를 설정하지 않으므로 기본값 20으로 설정됩니다.
Hibernate Java 구성 테스트
package com.journaldev.hibernate.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.journaldev.hibernate.model.Employee1;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateJavaConfigMain {
public static void main(String[] args) {
Employee1 emp = new Employee1();
emp.setName("Lisa");
emp.setRole("Manager");
emp.setInsertTime(new Date());
//세션 가져오기
SessionFactory sessionFactory = HibernateUtil.getSessionJavaConfigFactory();
Session session = sessionFactory.getCurrentSession();
//트랜잭션 시작
session.beginTransaction();
//모델 객체 저장
session.save(emp);
//트랜잭션 커밋
session.getTransaction().commit();
System.out.println("Employee ID="+emp.getId());
//세션 팩토리 종료, 그렇지 않으면 프로그램이 종료되지 않을 수 있음
sessionFactory.close();
}
}
위의 테스트 프로그램의 출력은 다음과 같습니다:
May 06, 2014 12:45:09 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:45:09 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:45:09 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:45:09 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Hibernate Java Config serviceRegistry created
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=pankaj, password=****}
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 06, 2014 12:45:10 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
May 06, 2014 12:45:10 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:45:10 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:45:10 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Employee ID=21
May 06, 2014 12:45:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]
이로써 초보자를 위한 Hibernate 튜토리얼은 여기까지입니다. 앞으로의 튜토리얼에서 Hibernate 프레임워크의 다양한 기능을 살펴보겠습니다. 아래 링크에서 전체 프로젝트를 다운로드하여 더 많이 배우기 위해 실험해보세요.
Source:
https://www.digitalocean.com/community/tutorials/hibernate-tutorial-for-beginners