수색…


비고

SessionFactory 빈은 TransactionManager 가 생성하도록 요청한 모든 데이터베이스 세션을 생성, 유지 보수, 종료 및 플러시한다. 이것이 우리가 DAO에 SessionFactory 를 autowire하고 그것을 통해 모든 쿼리를 실행하는 이유입니다.

새로운 Hibernate 사용자가 묻는 가장 큰 질문 중 하나는 "언제 내 변경 사항이 적용 되나요?"입니다. TransactionManager SesisonFactory 와 함께 작동하는 방식을 생각할 때 답이 SesisonFactory . @Transactional 로 주석 처리 된 서비스 메소드를 종료하면 데이터베이스 변경 사항이 플러시되고 커밋됩니다. 그 이유는 트랜잭션이 깨지지 않은 작업의 단일 단위를 나타 내기 때문입니다. 유닛에 문제가 발생하면 유닛이 실패하고 모든 변경 사항을 롤백해야한다고 가정합니다. 따라서 SessionFactory 는 원래 호출 한 서비스 메소드를 종료 할 때 세션을 비우고 지 웁니다.

그것은 트랜잭션이 진행되는 동안 세션을 비우고 지우지 않는다는 것을 의미하지는 않습니다. 예를 들어 서비스 메소드를 호출하여 5 개의 객체 컬렉션을 추가하고 데이터베이스에있는 객체의 총 개수를 반환하면 SessionFactory 는 쿼리 ( SELECT COUNT(*) )가 업데이트 된 상태가 정확해야 함을 인식하고 카운트 쿼리를 실행하기 전에 5 개의 객체를 추가 할 수 있습니다. 실행은 다음과 같이 보일 수 있습니다.

버전

번역 문서 링크 출시일
4.2.0 http://hibernate.org/orm/documentation/4.2/ 2013-03-01
4.3.0 http://hibernate.org/orm/documentation/4.3/ 2013-12-01
5.0.0 http://hibernate.org/orm/documentation/5.0/ 2015-09-01

XML 설정을 사용하여 Hibernate 설정하기

classpath 어딘가에 database-servlet.xml 파일을 생성합니다.

초기 설정 파일은 다음과 같습니다 :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

</beans>

txjdbc 스프링 네임 스페이스를 가져 tx 알 수 있습니다. 왜냐하면이 설정 파일에서 꽤 많이 사용하기 때문입니다.

제일 먼저하고 싶은 일은 주석 기반 트랜잭션 관리 ( @Transactional )를 가능하게하는 것입니다. 사람들이 Spring에서 Hibernate를 사용하는 주된 이유는 Spring이 당신을위한 모든 트랜잭션을 관리하기 때문입니다. 구성 파일에 다음 행을 추가하십시오.

<tx:annotation-driven />

데이터 소스를 만들어야합니다. 데이터 소스는 기본적으로 Hibernate가 객체를 유지하기 위해 사용할 데이터베이스입니다. 일반적으로 하나의 트랜잭션 관리자는 하나의 데이터 소스를 갖습니다. 당신이 Hibernate로 하여금 여러 데이터 소스들과 대화하기를 원한다면, 당신은 여러 트랜잭션 관리자들을 가진다.

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="" />
    <property name="url" value="" />
    <property name="username" value="" />
    <property name="password" value="" />
</bean>

이 bean의 클래스는 javax.sql.DataSource 를 구현하는 모든 것이 될 수 있으므로 직접 작성할 수 있습니다. 이 예제 클래스는 Spring에 의해 제공되지만 자체 스레드 풀을 가지고 있지 않습니다. 보편적 인 대안은 Apache Commons org.apache.commons.dbcp.BasicDataSource 이지만 다른 많은 것들이 있습니다. 아래의 각 속성에 대해 설명하겠습니다.

  • driverClassName : JDBC 드라이버의 경로. 이는 클래스 경로에서 사용할 수있는 데이터베이스 관련 JAR입니다. 가장 최신 버전인지 확인하십시오. Oracle 데이터베이스를 사용하는 경우 OracleDriver가 필요합니다. MySQL 데이터베이스가 있다면 MySQLDriver가 필요합니다. 여기에 필요한 드라이버를 찾을 수 있는지 확인 하십시오. 그러나 빠른 Google은 올바른 드라이버를 제공해야합니다.

  • url : 데이터베이스에 대한 URL입니다. 일반적으로 jdbc\:oracle\:thin\:\path\to\your\database 또는 jdbc:mysql://path/to/your/database . 사용중인 데이터베이스의 기본 위치에 대해 Google을 사용하는 경우이 항목을 찾아야합니다. org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set 메시지와 함께 HibernateException 이 발생하는 경우 org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set 되어 org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set 가이드를 따르고 있다면 URL이 잘못되었을 확률은 5 %이며 데이터베이스가 시작되지 않았고 사용자 이름 / 암호가 5 % 확률 적으로 잘못된 것입니다.

  • username : 데이터베이스를 인증 할 때 사용할 사용자 이름입니다.

  • 암호 : 데이터베이스를 인증 할 때 사용할 암호입니다.

다음은 SessionFactory 를 설정하는 것입니다. 이것은 Hibernate가 당신의 트랜잭션을 생성하고 관리하는데 사용하는 것이며, 실제로 데이터베이스와 대화한다. 아래에 설명하려고하는 몇 가지 구성 옵션이 있습니다.

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="au.com.project />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>
  • dataSource : 데이터 소스 빈. dataSource의 ID를 변경 한 경우 여기에 설정하십시오.

  • packagesToScan : JPA 주석 객체를 찾기 위해 스캔 할 패키지. 이것들은 세션 팩토리가 관리해야하는 객체이며, 일반적으로 POJO이고 @Entity 주석 처리됩니다. 최대 절전 모드에서 개체 관계를 설정하는 방법에 대한 자세한 내용 은 여기를 참조하십시오 .

  • annotatedClasses (not shown) : Hibernate가 모두 동일한 패키지에 있지 않으면 Hibernate가 스캔 할 클래스 목록을 제공 할 수도 있습니다. packagesToScan 또는 annotatedClasses 중 하나만 사용해야하며 둘 다 사용하면 안됩니다. 선언은 다음과 같습니다.

<property name="annotatedClasses">
    <list>
        <value>foo.bar.package.model.Person</value>
        <value>foo.bar.package.model.Thing</value>
    </list>
</property>
  • hibernateProperties : 무수히 많은 이들이 모두 여기에 사랑스럽게 문서화되어 있습니다 . 당신이 사용하게 될 주요 것들은 다음과 같습니다 :
  • hibernate.hbm2ddl.auto : 최대 절전 모드 질문 중 하나가이 속성에 대해 자세히 설명합니다. 자세한 내용은 그것을 참조하십시오 . 나는 일반적으로 validate를 사용하고 SQL 스크립트 (in-memory 용)를 사용하여 데이터베이스를 설정하거나 미리 데이터베이스 (기존 데이터베이스)를 만듭니다.
  • hibernate.show_sql : 부울 플래그. 참인 경우 Hibernate는 생성 한 모든 SQL을 stdout 인쇄합니다. 로그 관리자에서 log4j.logger.org.hibernate.type=TRACE log4j.logger.org.hibernate.SQL=DEBUG 를 설정하여 쿼리에 바인딩 된 값을 표시하도록 로거를 구성 할 수도 있습니다 (log4j를 사용합니다. ).
  • hibernate.format_sql : Boolean 플래그는 Hibernate로 하여금 당신의 SQL을 stdout으로 출력하게 만듭니다.
  • hibernate.dialect (정당한 이유없이) : 많은 오래된 튜토리얼은 Hibernate Dialect를 데이터베이스와 통신하는 데 사용하는 방법을 보여줍니다. Hibernate 사용중인 JDBC 드라이버를 기반으로 사용할 방언을 자동으로 탐지 할 수있다 . 약 3 개의 서로 다른 오라클 방언과 5 개의 다른 MySQL 방언이 있기 때문에 나는이 결정을 최대 절전 모드로 남겨 둘 것이다. Hibernate가 지원하는 방언의 전체 목록 은 여기를 참고하십시오 .

선언해야 할 마지막 두 개의 bean은 다음과 같습니다.

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"
    id="PersistenceExceptionTranslator" />

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

PersistenceExceptionTranslator 는 데이터베이스 특정 HibernateException 또는 SQLExceptions 를 응용 프로그램 컨텍스트가 이해할 수있는 Spring 예외로 변환합니다.

TransactionManager 빈은 롤백뿐만 아니라 트랜잭션을 제어합니다.

참고 : DAO에 SessionFactory bean을 autowiring해야합니다.

XML-less Hibernate 설정

이 예제는 여기 에서 가져 왔습니다 .

package com.reborne.SmartHibernateConnector.utils;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class LiveHibernateConnector implements IHibernateConnector {

    private String DB_DRIVER_NAME = "";
    private String DB_URL = "jdbc:h2:~/liveDB;MV_STORE=FALSE;MVCC=FALSE";
    private String DB_USERNAME = "sa";
    private String DB_PASSWORD = "";
    private String DIALECT = "org.hibernate.dialect.H2Dialect";
    private String HBM2DLL = "create";
    private String SHOW_SQL = "true";
    
    private static Configuration config;
    private static SessionFactory sessionFactory;
    private Session session;
    
    private boolean CLOSE_AFTER_TRANSACTION = false;

    public LiveHibernateConnector() {
        
        config = new Configuration();

        config.setProperty("hibernate.connector.driver_class",         DB_DRIVER_NAME);
        config.setProperty("hibernate.connection.url",                 DB_URL);
        config.setProperty("hibernate.connection.username",         DB_USERNAME);
        config.setProperty("hibernate.connection.password",         DB_PASSWORD);
        config.setProperty("hibernate.dialect",                     DIALECT);
        config.setProperty("hibernate.hbm2dll.auto",                 HBM2DLL);
        config.setProperty("hibernate.show_sql",                    SHOW_SQL);
    
        /*
         * Config connection pools
         */

        config.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
        config.setProperty("hibernate.c3p0.min_size", "5");
        config.setProperty("hibernate.c3p0.max_size", "20");
        config.setProperty("hibernate.c3p0.timeout", "300");
        config.setProperty("hibernate.c3p0.max_statements", "50");
        config.setProperty("hibernate.c3p0.idle_test_period", "3000");
        
        
        /**
         * Resource mapping
         */
        
//        config.addAnnotatedClass(User.class);
//        config.addAnnotatedClass(User.class);
//        config.addAnnotatedClass(User.class);
    
        sessionFactory = config.buildSessionFactory();
    }


    public HibWrapper openSession() throws HibernateException {
        return new HibWrapper(getOrCreateSession(), CLOSE_AFTER_TRANSACTION);
    }


    public Session getOrCreateSession() throws HibernateException {
        if (session == null) {
            session = sessionFactory.openSession();
        }
        return session;
    }

    public void reconnect() throws HibernateException {
        this.sessionFactory = config.buildSessionFactory();
    }

    
}

가장 최근의 Hibernate에서이 접근법은 잘 작동하지 않는다는 것을 기억하라. (Hibernate 5.2 release는 여전히이 구성을 허용한다)

XML을 사용하는 간단한 최대 절전 모드 예제

설정을 위해 XML을 사용하여 간단한 최대 절전 프로젝트를 설정하려면 hibernate.cfg.xml, 각 엔티티의 POJO, 각 엔티티의 EntityName.hbm.xml 파일이 필요합니다. 다음은 MySQL을 사용하는 각각의 예입니다.

hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
   </property>
   <property name="hibernate.connection.driver_class">
      com.mysql.jdbc.Driver
   </property>

   <property name="hibernate.connection.url">
      jdbc:mysql://localhost/DBSchemaName
   </property>
   <property name="hibernate.connection.username">
      testUserName
   </property>
   <property name="hibernate.connection.password">
      testPassword
   </property>

   <!-- List of XML mapping files -->
   <mapping resource="HibernatePractice/Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

DBSchemaName, testUserName 및 testPassword가 모두 바뀝니다. 패키지에있는 경우 전체 리소스 이름을 사용해야합니다.

Employee.java

package HibernatePractice;

public class Employee {
    private int id;
    private String firstName;
    private String middleName;
    private String lastName;
    
    public Employee(){
        
    }
    public int getId(){
        return id;
    }
    public void setId(int id){
        this.id = id;
    }
    public String getFirstName(){
        return firstName;
    }
    public void setFirstName(String firstName){
        this.firstName = firstName;
    }
    public String getMiddleName(){
        return middleName;
    }
    public void setMiddleName(String middleName){
        this.middleName = middleName;
    }
    public String getLastName(){
        return lastName;
    }
    public void setLastName(String lastName){
        this.lastName = lastName;
    }
}

Employee.hbm.xml

<hibernate-mapping>
   <class name="HibernatePractice.Employee" table="employee">
      <meta attribute="class-description">
         This class contains employee information. 
      </meta>
      <id name="id" type="int" column="empolyee_id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="middleName" column="middle_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
   </class>
</hibernate-mapping>

다시 말해, 클래스가 패키지에 있으면 전체 클래스 이름 인 packageName.className을 사용하십시오.

이 세 파일을 가지고 나면 프로젝트에서 최대 절전 모드를 사용할 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow