Heim  >  Artikel  >  Java  >  Ausführliche Erläuterung von Anmerkungen und Caching im Hibernate-Framework von Java

Ausführliche Erläuterung von Anmerkungen und Caching im Hibernate-Framework von Java

高洛峰
高洛峰Original
2017-01-23 11:53:301210Durchsuche

Anmerkungen
Hibernate-Anmerkungen sind eine neue Möglichkeit, Zuordnungen zu definieren, ohne XML-Dateien zu verwenden. Sie können Anmerkungen zusätzlich zu oder als Ersatz für XML-Zuordnungsmetadaten verwenden.

Hibernate-Anmerkungen sind eine leistungsstarke Möglichkeit, eine Zuordnung zwischen Metadatenobjekten und relationalen Tabellen bereitzustellen. Alle Metadaten werden im Code der POJO-Java-Datei zusammengefasst, was dem Benutzer hilft, sowohl die Tabellenstruktur als auch das POJO während des Entwicklungsprozesses zu verstehen.

Wenn Sie planen, Ihre Anwendung auf andere ORM-Anwendungen der EJB3-Spezifikation zu portieren, müssen Sie Anmerkungen verwenden, um Zuordnungsinformationen auszudrücken. Wenn Sie jedoch mehr Flexibilität wünschen, sollten Sie XML-basierte Zuordnungen verwenden.

Umgebungseinstellungen Annotationen in den Ruhezustand versetzen
Zunächst müssen Sie sicherstellen, dass Sie JDK5.0 verwenden. Andernfalls müssen Sie das JDK auf JDK5.0 aktualisieren, um die native Unterstützung von Annotationen nutzen zu können.

Zweitens müssen Sie das Hibernate 3.x-Annotationsverteilungspaket installieren, das Sie von SourceForge erhalten können: (Hibernate Annotation herunterladen) und hibernate-annotations.jar, lib/hibernate-comons-annotations.jar kopieren und lib/ejb3 -persistence.jar Weisen Sie die Klasseninstanz aus der Hibernate-Annotation der CLASSPATH

-Annotation zu:
Wie bei der Verwendung von Hibernate-Annotationen erwähnt, arbeiten Sie alle Metadaten zusammen mit dem obigen Code in die POJO-Java-Datei ein Dies hilft Benutzern, während des Entwicklungsprozesses gleichzeitig die Tabellenstruktur und POJO zu verstehen.

Betrachten Sie die Objekte, die mithilfe der folgenden EMPLOYEE-Tabelle gespeichert werden:

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 Anmerkungen, die zum Zuordnen und Definieren der Objekt-Mitarbeiterklasse des EMPLOYEE verwendet werden Tabellenzuordnung:

import javax.persistence.*;
 
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
  @Id @GeneratedValue
  @Column(name = "id")
  private int id;
 
  @Column(name = "first_name")
  private String firstName;
 
  @Column(name = "last_name")
  private String lastName;
 
  @Column(name = "salary")
  private int salary;
 
  public Employee() {}
  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;
  }
}

Hibernate erkennt, dass sich die @Id-Annotation auf einem Feld befindet und geht davon aus, dass der Zugriff direkt über die Laufzeitdomäne als Eigenschaft eines Objekts erfolgen sollte. Wenn Sie die getId()-Methode mit @Id annotieren, wird der Zugriff auf die Eigenschaft standardmäßig über Getter- und Setter-Methoden zugelassen. Daher werden auch alle anderen Anmerkungen gemäß der ausgewählten Strategie entweder auf der Feld- oder der Getter-Methode platziert. Im folgenden Abschnitt werden die in der obigen Klasse verwendeten Anmerkungen erläutert.

@Entity-Hinweis:
Die EJB3-Spezifikation ist im Paket javax.persistence enthalten, daher importieren wir dieses Paket als ersten Schritt. Zweitens haben wir die Annotation @Entity verwendet, um diese Klasse als Entity-Bean-Employee-Klasse zu markieren, sodass sie über einen Konstruktor ohne Parameter verfügen muss, der schließlich in einem geschützten Bereich sichtbar ist.

@Table-Annotation: Die
@Table-Annotation ermöglicht die Verwendung der angegebenen Tabelle zum Speichern der Details dieser Entität in der Datenbank.

Die @Table-Annotation stellt vier Eigenschaften bereit, die es ermöglichen, den Namen der Tabelle, ihr Verzeichnis, ihr Schema zu überschreiben und eindeutige Einschränkungen für Spalten innerhalb der Tabelle zu erzwingen. Jetzt verwenden wir den Namen der gerade angegebenen EMPLOYEE-Tabelle.

@Id- und @GeneratedValue-Annotationen:
Jede Entity-Bean verfügt über einen Primärschlüssel, der in der @Id-Annotation der Klasse annotiert ist. Der Primärschlüssel kann je nach Tabellenstruktur ein einzelnes Feld oder eine Kombination mehrerer Felder sein.

Standardmäßig bestimmt die @Id-Annotation automatisch die am besten geeignete Primärschlüsselgenerierungsstrategie. Dies kann jedoch durch Anwenden der @GeneratedValue-Annotation erreicht werden, die zwei Parameter akzeptiert, Strategie und Generator, die nicht vorgesehen sind Dies wird hier besprochen. Verwenden Sie einfach die Standardrichtlinie zur Schlüsselgenerierung. Indem Hibernate den zu verwendenden Generatortyp bestimmt, wird Code zwischen verschiedenen Datenbanken portierbar.

@Column-Annotation: Die
@Column-Annotation wird verwendet, um die Details einer Spalte anzugeben, der ein Feld oder Attribut zugeordnet wird. Die folgenden am häufigsten verwendeten Attribute können mit Spaltenanmerkungen verwendet werden:

Das Namensattribut

ermöglicht die explizite Angabe des Namens der Spalte. Das

length-Attribut ermöglicht die Verwendung der Größe einer Spalte zur Zuordnung eines Werts, insbesondere eines Zeichenfolgenwerts. Mit dem Attribut

nullable kann die Spalte beim Generieren des Schemas als NOT NULL markiert werden. Mit dem Attribut

unique können Spalten so markiert werden, dass sie nur eindeutige Werte enthalten.

Erstellen Sie die Anwendungsklasse:
Zuletzt erstellen wir die main()-Methode der Anwendungsklasse, um die Anwendung auszuführen. Wir werden diese Anwendung verwenden, um einige Mitarbeiterdatensätze zu speichern, und dann werden wir CRUD-Operationen auf die Datensätze anwenden.

import java.util.List;
import java.util.Date;
import java.util.Iterator;
  
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
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 AnnotationConfiguration().
          configure().
          //addPackage("com.xyz") //add package if used.
          addAnnotatedClass(Employee.class).
          buildSessionFactory();
   }catch (Throwable ex) {
     System.err.println("Failed to create sessionFactory object." + ex);
     throw new ExceptionInInitializerError(ex);
   }
   ManageEmployee ME = new ManageEmployee();
 
   /* Add few employee records in database */
   Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
   Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
   Integer empID3 = ME.addEmployee("John", "Paul", 10000);
 
   /* List down all the employees */
   ME.listEmployees();
 
   /* Update employee's records */
   ME.updateEmployee(empID1, 5000);
 
   /* Delete an employee from the database */
   ME.deleteEmployee(empID2);
 
   /* List down new list of the employees */
   ME.listEmployees();
  }
  /* Method to CREATE an employee in the database */
  public Integer addEmployee(String fname, String lname, int salary){
   Session session = factory.openSession();
   Transaction tx = null;
   Integer employeeID = null;
   try{
     tx = session.beginTransaction();
     Employee employee = new Employee();
     employee.setFirstName(fname);
     employee.setLastName(lname);
     employee.setSalary(salary);
     employeeID = (Integer) session.save(employee);
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
   return employeeID;
  }
  /* Method to READ all the employees */
  public void listEmployees( ){
   Session session = factory.openSession();
   Transaction tx = null;
   try{
     tx = session.beginTransaction();
     List employees = session.createQuery("FROM Employee").list();
     for (Iterator iterator =
              employees.iterator(); iterator.hasNext();){
      Employee employee = (Employee) iterator.next();
      System.out.print("First Name: " + employee.getFirstName());
      System.out.print(" Last Name: " + employee.getLastName());
      System.out.println(" Salary: " + employee.getSalary());
     }
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
  }
  /* Method to UPDATE salary for an employee */
  public void updateEmployee(Integer EmployeeID, int salary ){
   Session session = factory.openSession();
   Transaction tx = null;
   try{
     tx = session.beginTransaction();
     Employee employee =
          (Employee)session.get(Employee.class, EmployeeID);
     employee.setSalary( salary );
  session.update(employee);
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
  }
  /* Method to DELETE an employee from the records */
  public void deleteEmployee(Integer EmployeeID){
   Session session = factory.openSession();
   Transaction tx = null;
   try{
     tx = session.beginTransaction();
     Employee employee =
          (Employee)session.get(Employee.class, EmployeeID);
     session.delete(employee);
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
  }
}

Datenbankkonfiguration:
Lassen Sie uns nun die Konfigurationsdatei hibernate.cfg.xml erstellen, um die relevanten Parameter der Datenbank zu definieren.

<?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">
   cohondob
  </property>
 
</session-factory>
</hibernate-configuration>

Kompilieren und Ausführen:
Nachfolgend finden Sie die Schritte zum Kompilieren und Ausführen der oben genannten Anwendung. Bitte stellen Sie sicher, dass PATH und CLASSPATH vor der Kompilierung und Ausführung richtig eingestellt sind.

Entfernen Sie die Zuordnungsdatei Employee.hbm.xml aus dem Pfad.

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.

erhält die folgenden Ergebnisse und die Datensätze werden in der EMPLOYEE-Tabelle angezeigt.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
 
First Name: Zara Last Name: Ali Salary: 1000
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 10000
First Name: Zara Last Name: Ali Salary: 5000
First Name: John Last Name: Paul Salary: 10000

Wenn Sie die EMPLOYEE-Tabelle überprüfen, sollte sie die folgenden Datensätze enthalten:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara    | Ali    |  5000 |
| 31 | John    | Paul   | 10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
 
mysql>

Caching
Beim Caching geht es um die Optimierung der Anwendungsleistung und Es befindet sich zwischen der Anwendung und der Datenbank, um mehrfache Datenbankzugriffe zu vermeiden und eine bessere Leistung leistungskritischer Anwendungen zu ermöglichen.

Caching ist für Hibernate sehr wichtig, das ein mehrstufiges Caching-Schema verwendet, wie unten beschrieben:

Ausführliche Erläuterung von Anmerkungen und Caching im Hibernate-Framework von Java

第一级缓存:
第一级缓存是Session的缓存,是一个强制性的缓存,通过它所有的请求都必须通过。 Session对象不断自身的动力的对象,提交到数据库之前。

如果发出多个更新一个对象,Hibernate试图拖延尽可能长的时间做了更新,以减少发出的更新SQL语句的数量。如果您关闭会话,所有被缓存的对象都将丢失,要么持久,或在数据库中更新。

二级缓存:
二级缓存是可选的缓存和一级缓存,总是会征询任何试图找到一个对象的二级缓存之前。第二级缓存可以在每个类和每个集合基础上进行配置,主要负责在会话缓存的对象。

任何第三方缓存可以使用Hibernate。org.hibernate.cache.CacheProvider接口提供,必须实施提供Hibernate一个句柄缓存实现。

查询级别缓存:
Hibernate也实现了查询结果集缓存与二级缓存的紧密集成在一起。

这是一个可选功能,需要两个额外的物理缓存中保存缓存的查询结果和地区当一个表的最后更新的时间戳。这只是针对那些使用相同的参数经常运行的查询非常有用。

二级缓存:
Hibernate使用一级缓存,默认情况下,你什么都没有做使用第一级缓存。让我们直接进入可选的第二级缓存。并不是所有的类受益于缓存,这样一来就能禁用二级缓存是很重要的

Hibernate二级缓存被设置为两个步骤。首先,必须决定要使用的并发策略。在此之后,可以配置缓存过期和使用缓存提供物理缓存属性。

并发策略:
并发策略是一个中介的负责存储数据项在缓存并从缓存中检索它们。如果要启用二级缓存,将必须决定,为每个持久化类和集合,要使用的缓存并发策略。

Transactional: 使用这种策略的主要读取数据的地方,以防止过时的数据的并发事务,在更新的罕见情况下是至关重要的。

Read-write: 再次使用这种策略的主要读取数据的地方,以防止并发事务陈旧的数据是至关重要的,在更新的罕见情况。

Nonstrict-read-write: 这种策略不保证缓存与数据库之间的一致性。使用此策略,如果数据很少改变和陈旧数据的可能性很小关键是不关注。

Read-only: 并发策略适用于数据,永远不会改变。使用数据仅供参考。

如果我们要使用第二级缓存为我们的Employee类,让我们添加告诉Hibernate使用可读写的高速缓存策略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>
   <cache usage="read-write"/>
   <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>

 usage="read-write" 属性告诉Hibernate使用一个可读写的并发策略定义的缓存。

缓存提供者:
考虑到会用你的缓存候选类的并发策略后,下一步就是选择一个缓存提供程序。Hibernate迫使选择一个缓存提供整个应用程序。

Ausführliche Erläuterung von Anmerkungen und Caching im Hibernate-Framework von Java

在指定hibernate.cfg.xml配置文件中的缓存提供。选择EHCache作为第二级缓存提供程序:

<?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.cache.provider_class">
   org.hibernate.cache.EhCacheProvider
  </property>
 
  <!-- List of XML mapping files -->
  <mapping resource="Employee.hbm.xml"/>
 
</session-factory>
</hibernate-configuration>

现在,需要指定缓存区域的属性。EHCache都有自己的配置文件ehcache.xml,在应用程序在CLASSPATH中。在ehcache.xml中Employee类高速缓存配置可能看起来像这样:

<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
 
<cache name="Employee"
maxElementsInMemory="500"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>

就这样,现在启用Employee类的二级缓存和Hibernate现在二级缓存,每当浏览到一个雇员或当通过标识符加载雇员。

应该分析你所有的类,并选择适当的缓存策略为每个类。有时,二级缓存可能降级的应用程序的性能。所以建议到基准应用程序第一次没有启用缓存,非常适合缓存和检查性能。如果缓存不提高系统性能再有就是在使任何类型的缓存是没有意义的。

查询级别缓存:
使用查询缓存,必须先使用 hibernate.cache.use_query_cache="true"属性配置文件中激活它。如果将此属性设置为true,让Hibernate的在内存中创建所需的高速缓存来保存查询和标识符集。

接下来,使用查询缓存,可以使用Query类的setCacheable(Boolean)方法。例如:

Session session = SessionFactory.openSession();

Query query = session.createQuery("FROM EMPLOYEE");

query.setCacheable(true);

List users = query.list();

SessionFactory.closeSession();

Hibernate也支持通过一个缓存区域的概念非常细粒度的缓存支持。缓存区是这是给定一个名称缓存的一部分。

Session session = SessionFactory.openSession();

Query query = session.createQuery("FROM EMPLOYEE");

query.setCacheable(true);

query.setCacheRegion("employee");

Benutzer auflisten = query.list();

SessionFactory.closeSession();

Diese Codeverwendungsmethode gibt Auskunft Der Ruhezustand wird verwendet, um die Mitarbeiteraspekte der Abfrage im Cache zu speichern und nachzuschlagen.

Ausführlichere Artikel zu Anmerkungen und Caching im Hibernate-Framework von Java finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn