详解Java的Hibernate框架中的注解与缓存

时间:2021-05-19

注解
Hibernate注解是一个没有使用XML文件来定义映射的最新方法。可以在除或替换的XML映射元数据使用注解。

Hibernate的注解是强大的方式来提供元数据对象和关系表的映射。所有的元数据被杵到一起的代码POJO java文件这可以帮助用户在开发过程中同时要了解表的结构和POJO。

如果打算让应用程序移植到其他EJB3规范的ORM应用程序,必须使用注解来表示映射信息,但仍然如果想要更大的灵活性,那么应该使用基于XML的映射去。

环境设置Hibernate注释
首先,必须确保使用的是JDK5.0,否则,需要JDK升级到JDK5.0带注解的原生支持的优势。

其次,需要安装Hibernate的3.x注解分发包,可从SourceForge上: (Download Hibernate Annotation) 并拷贝 hibernate-annotations.jar, lib/hibernate-comons-annotations.jar 和 lib/ejb3-persistence.jar 从Hibernate注解分配到CLASSPATH

注释的类实例:
正如提到的,同时使用Hibernate注释工作的所有元数据杵成随着代码的POJO java文件上面这可以帮助用户在开发过程中同时了解表结构和POJO。

考虑到将要使用下面的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类的映射:

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检测@Id注释是对一个字段,并假设它应该直接通过在运行时域访问一个对象的属性。如果将@Id注释getId()方法,将通过getter和setter方法​​默认情况下允许访问属性。因此,所有其他注释也被放置在任一字段或getter方法​​,以下所选择的策略。下面的部分将解释在上面的类中使用的注释。

@Entity 注解:
在EJB3规范说明都包含在javax.persistence包,所以我们导入这个包作为第一步。其次,我们使用了@Entity注解来这标志着这个类作为一个实体bean Employee类,因此它必须有一个无参数的构造函数,总算是有保护的范围可见。

@Table 注解:
@Table注释允许指定的表将被用于保存该实体在数据库中的详细信息。

@Table注释提供了四个属性,允许覆盖表的名称,它的目录,它的架构,并执行对列的唯一约束在表中。现在,我们使用的是刚刚是EMPLOYEE表的名称。

@Id 和 @GeneratedValue 注解:
每个实体bean将有一个主键,注释在类的@Id注解。主键可以是单个字段或根据表结构的多个字段的组合。

默认情况下,@Id注解会自动确定要使用的最合适的主键生成策略,但可以通过应用@GeneratedValue注释,它接受两个参数,strategy和generator,不打算在这里讨论,只使用默认的默认键生成策略。让Hibernate确定要使用的generator类型使不同数据库之间代码的可移植性。

@Column 注解:
@Column批注用于指定的列到一个字段或属性将被映射的细节。可以使用列注释以下最常用的属性:

name属性允许将显式指定列的名称。

length 属性允许用于映射一个value尤其是对一个字符串值的列的大小。

nullable 属性允许该列被标记为NOT NULL生成架构时。

unique 属性允许被标记为只包含唯一值的列。

创建应用程序类:
最后,我们将创建应用程序类的main()方法来运行应用程序。我们将使用这个应用程序,以节省一些员工的记录,然后我们将申请CRUD操作上的记录。

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(); Integer empID1 = ME.addEmployee("Zara", "Ali", 1000); Integer empID2 = ME.addEmployee("Daisy", "Das", 5000); Integer empID3 = ME.addEmployee("John", "Paul", 10000); ME.listEmployees(); ME.updateEmployee(empID1, 5000); ME.deleteEmployee(empID2); ME.listEmployees(); } 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; } 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(); } } 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(); } } 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(); } }}

数据库配置:
现在,让我们创建hibernate.cfg.xml配置文件来定义数据库的相关参数。

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration SYSTEM "http://.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"/><defaultCachemaxElementsInMemory="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");
  • List users = query.list();
  • SessionFactory.closeSession();

此代码使用方法告诉Hibernate来存储和查找在缓存中的员工方面的查询。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章