Hibernate-일괄 처리
Hibernate를 사용하여 데이터베이스에 많은 레코드를 업로드해야하는 상황을 고려하십시오. 다음은 Hibernate를 사용하여 이것을 달성하는 코드 스 니펫입니다-
Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Employee employee = new Employee(.....);
session.save(employee);
}
tx.commit();
session.close();
기본적으로 Hibernate는 세션 수준 캐시에있는 모든 지속 된 객체를 캐시하고 궁극적으로 응용 프로그램은 OutOfMemoryException50,000 번째 줄 어딘가. 다음을 사용하는 경우이 문제를 해결할 수 있습니다.batch processing Hibernate로.
일괄 처리 기능을 사용하려면 먼저 hibernate.jdbc.batch_size개체 크기에 따라 배치 크기를 20 또는 50으로 설정합니다. 이것은 최대 절전 모드 컨테이너에 모든 X 행이 배치로 삽입되도록 알려줍니다. 이를 코드에서 구현하려면 다음과 같이 약간의 수정이 필요합니다.
Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Employee employee = new Employee(.....);
session.save(employee);
if( i % 50 == 0 ) { // Same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
위의 코드는 INSERT 작업에 대해 잘 작동하지만 UPDATE 작업을 수행하려는 경우 다음 코드를 사용하여 수행 할 수 있습니다.
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults employeeCursor = session.createQuery("FROM EMPLOYEE").scroll();
int count = 0;
while ( employeeCursor.next() ) {
Employee employee = (Employee) employeeCursor.get(0);
employee.updateEmployee();
seession.update(employee);
if ( ++count % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();
일괄 처리 예
추가 할 구성 파일을 수정하겠습니다. hibernate.jdbc.batch_size 재산 −
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/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>
<!-- Assume students is the database name -->
<property name = "hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name = "hibernate.connection.username">
root
</property>
<property name = "hibernate.connection.password">
root123
</property>
<property name = "hibernate.jdbc.batch_size">
50
</property>
<!-- List of XML mapping files -->
<mapping resource = "Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
다음 POJO Employee 클래스를 고려하십시오-
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}
Employee 객체를 저장하기 위해 다음 EMPLOYEE 테이블을 생성 해 보겠습니다.
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
다음은 EMPLOYEE 테이블로 Employee 개체를 매핑하는 매핑 파일입니다-
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">
<meta attribute = "class-description">
This class contains the employee detail.
</meta>
<id name = "id" type = "int" column = "id">
<generator class="native"/>
</id>
<property name = "firstName" column = "first_name" type = "string"/>
<property name = "lastName" column = "last_name" type = "string"/>
<property name = "salary" column = "salary" type = "int"/>
</class>
</hibernate-mapping>
마지막으로 main () 메소드를 사용하여 애플리케이션 클래스를 생성하여 사용할 애플리케이션을 실행합니다. flush() 과 clear() 세션 객체와 함께 사용할 수있는 메소드를 통해 Hibernate는 이러한 레코드를 메모리에 캐시하는 대신 데이터베이스에 계속 기록합니다.
import java.util.*;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try {
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();
/* Add employee records in batches */
ME.addEmployees( );
}
/* Method to create employee records in batches */
public void addEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try {
tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
String fname = "First Name " + i;
String lname = "Last Name " + i;
Integer salary = i;
Employee employee = new Employee(fname, lname, salary);
session.save(employee);
if( i % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return ;
}
}
컴파일 및 실행
위에서 언급 한 애플리케이션을 컴파일하고 실행하는 단계는 다음과 같습니다. 컴파일 및 실행을 계속하기 전에 PATH 및 CLASSPATH를 적절하게 설정했는지 확인하십시오.
위에서 설명한대로 hibernate.cfg.xml 구성 파일을 만듭니다.
위와 같이 Employee.hbm.xml 매핑 파일을 생성합니다.
위와 같이 Employee.java 소스 파일을 생성하고 컴파일합니다.
위와 같이 ManageEmployee.java 소스 파일을 생성하고 컴파일합니다.
ManageEmployee 바이너리를 실행하여 프로그램을 실행하면 EMPLOYEE 테이블에 100000 개의 레코드가 생성됩니다.