hibernate 拦截器
hibernate 中的对象将被创建和保持。一旦对象被修改,它必须被保存到数据库里。这个过程持续直到下一次对象被需要,它将被从持久的存储中加载。
因此一个对象通过它生命周期中的不同阶段,并且 interceptor 接口提供了在不同阶段能被调用来进行一些所需要的任务的方法。这些方法是从会话到应用程序的回调函数,允许应用程序检查或操作一个持续对象的属性,在它被保存,更新,删除或上传之前。以下是在 interceptor 接口中可用的所有方法的列表。
| s.n. | 方法和描述 |
|---|---|
| 1 | finddirty() 这个方法在当 flush() 方法在一个 session 对象上被调用时被调用。 |
| 2 | instantiate() 这个方法在一个持续的类被实例化时被调用。 |
| 3 | isunsaved() 这个方法在当一个对象被传到 saveorupdate() 方法时被调用。 |
| 4 | ondelete() 这个方法在一个对象被删除前被调用。 |
| 5 | onflushdirty() 这个方法在当 hibernate 探测到一个对象在一次 flush(例如,更新操作)中是脏的(例如,被修改)时被调用。 |
| 6 | onload() 这个方法在一个对象被初始化之前被调用。 |
| 7 | onsave() 这个方法在一个对象被保存前被调用。 |
| 8 | postflush() 这个方法在一次 flush 已经发生并且一个对象已经在内存中被更新后被调用。 |
| 9 | preflush() 这个方法在一次 flush 前被调用。 |
hibernate 拦截器给予了我们一个对象如何应用到应用程序和数据库的总控制。
如何使用拦截器?
为了创建一个拦截器你可以直接实现 interceptor 类或者继承 emptyinterceptor 类。以下是简单的使用 hibernate 拦截器功能的步骤。
创建拦截器
我们将在例子中继承 emptyinterceptor,当 employee 对象被创建和更新时拦截器的方法将自动被调用。你可以根据你的需求实现更多的方法。
import java.io.serializable;
import java.util.date;
import java.util.iterator;
import org.hibernate.emptyinterceptor;
import org.hibernate.transaction;
import org.hibernate.type.type;
public class myinterceptor extends emptyinterceptor {
private int updates;
private int creates;
private int loads;
public void ondelete(object entity,
serializable id,
object[] state,
string[] propertynames,
type[] types) {
// do nothing
}
// this method is called when employee object gets updated.
public boolean onflushdirty(object entity,
serializable id,
object[] currentstate,
object[] previousstate,
string[] propertynames,
type[] types) {
if ( entity instanceof employee ) {
system.out.println("update operation");
return true;
}
return false;
}
public boolean onload(object entity,
serializable id,
object[] state,
string[] propertynames,
type[] types) {
// do nothing
return true;
}
// this method is called when employee object gets created.
public boolean onsave(object entity,
serializable id,
object[] state,
string[] propertynames,
type[] types) {
if ( entity instanceof employee ) {
system.out.println("create operation");
return true;
}
return false;
}
//called before commit into database
public void preflush(iterator iterator) {
system.out.println("preflush");
}
//called after committed into database
public void postflush(iterator iterator) {
system.out.println("postflush");
}
}
创建 pojo 类
现在让我们稍微修改我们的第一个例子,我们使用 employee 表单和 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;
}
}
创建数据库表
第二步将是在你的数据库中创建表。一张表对应每个你提供持久性的对象。考虑以上的对象需要被存储和检索到以下的 rdbm 表中:
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) );
创建 mapping 配置文件
这个步骤是来创建一个指导 hibernate 如何将定义的类或者多个类映射到数据库表单中的映射文件。
<?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>
创建 application 类
最后,我们将用 main() 创建 application 类来运行应用程序。这里应该注意当创建 session 对象时我们使用 interceptor 类作为参数。
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.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 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( new myinterceptor() );
transaction tx = null;
integer employeeid = null;
try{
tx = session.begintransaction();
employee employee = new employee(fname, lname, 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( new myinterceptor() );
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( new myinterceptor() );
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( new myinterceptor() );
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();
}
}
}
编译和执行
这里是编译和运行上面提及的应用程序的步骤。确保你已经在处理编译和执行前正确设置了 path 和 classpath。
- 创建在 configuration 章节中解释的 hibernate.cfg.xml 配置文件。
- 创建如上所示的 employee.hbm.xml 映射文件。
- 创建如上所示的 employee.java 源文件并编译。
- 创建如上所示的 myinterceptor.java 源文件并编译。
- 创建如上所示的 manageemployee.java 源文件并编译。
- 执行 manageemployee 来运行程序。
你将得到以下结果,而且记录将在 employee 表单中被创建。
$java manageemployee .......various log messages will display here........ create operation preflush postflush create operation preflush postflush create operation preflush postflush first name: zara last name: ali salary: 1000 first name: daisy last name: das salary: 5000 first name: john last name: paul salary: 10000 preflush postflush preflush update operation postflush preflush postflush first name: zara last name: ali salary: 5000 first name: john last name: paul salary: 10000 preflush postflush
如果你检查你的 employee 表单,它应该有如下结果:
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>


