Ruhezustand - Stapelverarbeitung
Stellen Sie sich eine Situation vor, in der Sie mithilfe des Ruhezustands eine große Anzahl von Datensätzen in Ihre Datenbank hochladen müssen. Im Folgenden finden Sie das Code-Snippet, um dies mit Hibernate zu erreichen.
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();
Standardmäßig werden im Ruhezustand alle persistierten Objekte im Cache auf Sitzungsebene zwischengespeichert, und letztendlich würde Ihre Anwendung mit einem umfallen OutOfMemoryExceptionirgendwo um die 50.000ste Reihe. Sie können dieses Problem beheben, wenn Sie verwendenbatch processing mit Ruhezustand.
Um die Stapelverarbeitungsfunktion zu verwenden, legen Sie zuerst fest hibernate.jdbc.batch_sizeals Stapelgröße auf eine Zahl bei 20 oder 50, abhängig von der Objektgröße. Dadurch wird dem Ruhezustandscontainer mitgeteilt, dass alle X Zeilen als Stapel eingefügt werden sollen. Um dies in Ihrem Code zu implementieren, müssten wir wie folgt nur wenige Änderungen vornehmen:
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();
Der obige Code funktioniert gut für die INSERT-Operation. Wenn Sie jedoch bereit sind, eine UPDATE-Operation durchzuführen, können Sie den folgenden Code verwenden:
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();
Beispiel für die Stapelverarbeitung
Lassen Sie uns die hinzuzufügende Konfigurationsdatei ändern hibernate.jdbc.batch_size Eigentum -
<?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>
Betrachten Sie die folgende POJO-Mitarbeiterklasse -
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;
}
}
Erstellen wir die folgende EMPLOYEE-Tabelle zum Speichern der Employee-Objekte:
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)
);
Im Folgenden finden Sie die Zuordnungsdatei zum Zuordnen der Mitarbeiterobjekte mit der Tabelle 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>
Schließlich erstellen wir unsere Anwendungsklasse mit der main () -Methode, um die Anwendung dort auszuführen, wo wir sie verwenden werden flush() und clear() Mit dem Sitzungsobjekt verfügbare Methoden, damit Hibernate diese Datensätze weiterhin in die Datenbank schreibt, anstatt sie im Speicher zwischenzuspeichern.
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 ;
}
}
Zusammenstellung und Ausführung
Hier sind die Schritte zum Kompilieren und Ausführen der oben genannten Anwendung. Stellen Sie sicher, dass Sie PATH und CLASSPATH entsprechend eingestellt haben, bevor Sie mit der Kompilierung und Ausführung fortfahren.
Erstellen Sie die Konfigurationsdatei hibernate.cfg.xml wie oben erläutert.
Erstellen Sie die Zuordnungsdatei Employee.hbm.xml wie oben gezeigt.
Erstellen Sie die Quelldatei Employee.java wie oben gezeigt und kompilieren Sie sie.
Erstellen Sie die Quelldatei ManageEmployee.java wie oben gezeigt und kompilieren Sie sie.
Führen Sie die ManageEmployee-Binärdatei aus, um das Programm auszuführen, mit dem 100000 Datensätze in der Tabelle EMPLOYEE erstellt werden.