Looking for hibernate Keywords? Try Ask4Keywords

hibernateErste Schritte mit dem Winterschlaf


Bemerkungen

Die SessionFactory Bean ist für das Erstellen, SessionFactory , Schließen und Leeren aller Datenbanksitzungen verantwortlich, die der TransactionManager zur Erstellung SessionFactory . Deshalb automatisieren wir die SessionFactory SessionFactory in SessionFactory und führen alle Abfragen durch.

Eine der größten Fragen, die neue Benutzer von Hibernate stellen, lautet: "Wann werden meine Änderungen festgeschrieben?" Die Antwort ist sinnvoll, wenn Sie SesisonFactory , wie der TransactionManager mit der SesisonFactory . Ihre Datenbankänderungen werden gelöscht und festgeschrieben, wenn Sie die mit @Transactional kommentierte @Transactional . Der Grund dafür ist, dass eine Transaktion eine einzelne "Einheit" der ununterbrochenen Arbeit darstellen soll. Wenn mit dem Gerät etwas schief geht, wird davon ausgegangen, dass das Gerät ausgefallen ist und alle Änderungen rückgängig gemacht werden sollten. Die SessionFactory und SessionFactory die Sitzung, wenn Sie die ursprünglich aufgerufene Service-Methode SessionFactory .

Das bedeutet nicht, dass die Sitzung nicht gelöscht und gelöscht wird, während Ihre Transaktion läuft. Wenn ich beispielsweise eine Servicemethode aufrufe, um eine Sammlung von 5 Objekten hinzuzufügen und die Gesamtanzahl der Objekte in der Datenbank zurückgeben, würde die SessionFactory erkennen, dass die Abfrage ( SELECT COUNT(*) ) einen aktualisierten Status erfordert, und Dadurch würden die 5 Objekte vor dem Ausführen der Count-Abfrage gelöscht. Die Ausführung könnte ungefähr so ​​aussehen:

Versionen

Ausführung Dokumentationslink Veröffentlichungsdatum
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

Einfaches Beispiel für den Ruhezustand mithilfe von XML

Zum Einrichten eines einfachen Hibernate-Projekts mit XML für die Konfigurationen benötigen Sie 3 Dateien, hibernate.cfg.xml, einen POJO für jede Entität und eine EntityName.hbm.xml für jede Entität. Hier ist ein Beispiel für die Verwendung von 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 und testPassword würden alle ersetzt. Stellen Sie sicher, dass Sie den vollständigen Ressourcennamen verwenden, wenn er sich in einem Paket befindet.

Mitarbeiter.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>
 

Wenn sich die Klasse in einem Paket befindet, verwenden Sie erneut den vollständigen Klassennamen packageName.className.

Nachdem Sie diese drei Dateien erworben haben, können Sie den Ruhezustand in Ihrem Projekt verwenden.

Verwenden der XML-Konfiguration zum Einrichten des Ruhezustands

Ich erstelle eine Datei namens database-servlet.xml irgendwo im Klassenpfad.

Anfangs sieht Ihre Konfigurationsdatei folgendermaßen aus:

<?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>
 

Sie werden feststellen, dass ich die Namespaces tx und jdbc Spring importiert habe. Das liegt daran, dass wir sie in dieser Konfigurationsdatei ziemlich stark verwenden werden.

Zuerst möchten Sie die Annotations-basierte Transaktionsverwaltung ( @Transactional ) @Transactional . Der Hauptgrund, aus dem die Benutzer den Ruhezustand im Frühling verwenden, besteht darin, dass Frühling alle Ihre Transaktionen für Sie verwaltet. Fügen Sie Ihrer Konfigurationsdatei die folgende Zeile hinzu:

<tx:annotation-driven />
 

Wir müssen eine Datenquelle erstellen. Die Datenquelle ist im Wesentlichen die Datenbank, in der Hibernate Ihre Objekte persistiert. Im Allgemeinen verfügt ein Transaktionsmanager über eine Datenquelle. Wenn Sie möchten, dass Hibernate mit mehreren Datenquellen kommuniziert, verfügen Sie über mehrere Transaktionsmanager.

<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>
 

Die Klasse dieser Bean kann alles sein, was javax.sql.DataSource implementiert, damit Sie Ihre eigene schreiben können. Diese Beispielklasse wird von Spring bereitgestellt, verfügt jedoch nicht über einen eigenen Thread-Pool. Eine beliebte Alternative ist die Apache Commons org.apache.commons.dbcp.BasicDataSource , aber es gibt noch viele andere. Ich werde jede der Eigenschaften unten erklären:

  • driverClassName : Der Pfad zu Ihrem JDBC-Treiber. Dies ist eine datenbankspezifische JAR, die in Ihrem Klassenpfad verfügbar sein sollte. Stellen Sie sicher, dass Sie über die aktuellste Version verfügen. Wenn Sie eine Oracle-Datenbank verwenden, benötigen Sie einen Oracle-Treiber. Wenn Sie eine MySQL-Datenbank haben, benötigen Sie einen MySQLDriver. Sehen Sie hier , ob Sie den benötigten Treiber finden, aber ein schneller Google-Befehl sollte Ihnen den richtigen Treiber geben.

  • URL : Die URL zu Ihrer Datenbank. Normalerweise handelt es sich dabei um jdbc\:oracle\:thin\:\path\to\your\database oder jdbc:mysql://path/to/your/database . Wenn Sie nach dem Standardspeicherort der von Ihnen verwendeten Datenbank suchen, sollten Sie in der Lage sein, herauszufinden, wie dies aussehen soll. Wenn Sie eine HibernateException mit der Nachricht org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set und Sie diesem Leitfaden folgen. Es besteht eine Wahrscheinlichkeit von 90%, dass Ihre URL falsch ist, eine Chance von 5% dass Ihre Datenbank nicht gestartet ist und eine 5% ige Chance besteht, dass Ihr Benutzername / Passwort falsch ist.

  • Benutzername : Der Benutzername, der bei der Authentifizierung bei der Datenbank verwendet werden soll.

  • Kennwort : Das Kennwort, das bei der Authentifizierung bei der Datenbank verwendet werden soll.

Als nächstes müssen Sie die SessionFactory . Dies ist die Sache, die Hibernate verwendet, um Ihre Transaktionen zu erstellen und zu verwalten und tatsächlich mit der Datenbank zu kommunizieren. Es gibt einige Konfigurationsoptionen, die ich im Folgenden erläutern möchte.

<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 : Ihre Datenquellen-Bean. Wenn Sie die ID der dataSource geändert haben, legen Sie sie hier fest.

  • packagesToScan : Die zu durchsuchenden Pakete, um Ihre mit JPA gekennzeichneten Objekte zu finden. Dies sind die Objekte, die von der Sitzungsfabrik verwaltet werden müssen. Sie werden im Allgemeinen als @Entity und mit @Entity . Weitere Informationen zum Einrichten von Objektbeziehungen in Hibernate finden Sie hier .

  • annotatedClasses (nicht gezeigt): Sie können auch eine Liste von Klassen bereitstellen, die Hibernate durchsuchen soll, wenn sie nicht alle im selben Paket enthalten sind. Sie sollten entweder packagesToScan oder annotatedClasses jedoch nicht beides. Die Deklaration sieht folgendermaßen aus:

<property name="annotatedClasses">
    <list>
        <value>foo.bar.package.model.Person</value>
        <value>foo.bar.package.model.Thing</value>
    </list>
</property>
 
  • hibernateProperties : Es gibt unzählige davon, die hier liebevoll dokumentiert sind . Die wichtigsten, die Sie verwenden werden, lauten wie folgt:
  • hibernate.hbm2ddl.auto : Eine der heißesten Hibernate-Fragen beschreibt diese Eigenschaft. Weitere Informationen finden Sie hier . Im Allgemeinen verwende ich validate und konfiguriere meine Datenbank entweder mit SQL-Skripts (für einen In-Memory) oder erstelle die Datenbank zuvor (vorhandene Datenbank).
  • hibernate.show_sql : Boolean-Flag, wenn true, wenn der Wert für "Hibernate" alle SQL- stdout die von ihm generiert werden. Sie können Ihren Logger auch so konfigurieren, dass er Ihnen die Werte log4j.logger.org.hibernate.type=TRACE , die an die Abfragen gebunden sind, indem Sie log4j.logger.org.hibernate.type=TRACE log4j.logger.org.hibernate.SQL=DEBUG in Ihrem Protokollmanager (ich verwende log4j ).
  • hibernate.format_sql : Boolean-Flag, bewirkt, dass Hibernate Ihre SQL-Datei ziemlich stdout ausgibt.
  • hibernate.dialect (aus gutem Grund nicht gezeigt): Viele alte Tutorials zeigen Ihnen, wie Sie den Hibernate-Dialekt einstellen, den er für die Kommunikation mit Ihrer Datenbank verwendet. Der Ruhezustand kann basierend auf dem von Ihnen verwendeten JDBC-Treiber automatisch erkennen, welcher Dialekt verwendet werden soll. Da es ungefähr 3 verschiedene Oracle-Dialekte und 5 verschiedene MySQL-Dialekte gibt, überlasse ich diese Entscheidung dem Hibernate. Eine vollständige Liste von Dialekten finden Sie hier .

Die letzten 2 Beans, die Sie deklarieren müssen, sind:

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

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

Der PersistenceExceptionTranslator übersetzt datenbankspezifische HibernateException oder SQLExceptions in Spring-Ausnahmen, die vom Anwendungskontext verstanden werden können.

Die TransactionManager Bean steuert sowohl die Transaktionen als auch das Rollback.

Hinweis: Sie sollten Ihre SessionFactory Bean automatisch in Ihre SessionFactory übernehmen.

XML-lose Hibernate-Konfiguration

Dieses Beispiel wurde von genommen hier

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();
    }

    
}
 

Bitte beachten Sie, dass dieser Ansatz mit dem neuesten Hibernate nicht gut funktioniert (Hibernate 5.2-Release lässt diese Konfiguration immer noch zu.)