hibernate中的Interceptor

讲到Interceptor,相信熟悉struts2的童鞋肯定不会陌生了,struts2可以自定义拦截器进行自己想要的一系列相关的工作。而这里我们说的Interceptor也是差不多相似的功能。

废话不说,直接来代码:

下面这个是MyInterceptor类,它实现了Interceptor接口:

public String onPrepareStatement(String arg0) {
	return arg0;
}

public boolean onSave(Object arg0, Serializable arg1, Object[] arg2,
		String[] arg3, Type[] arg4) throws CallbackException {
	if (arg0 instanceof User) {
		System.out.println("User to be saved=>"+((User)arg0).getName());
	}
	return false;
}

  其他方法就不看了,按默认实现就行,我们只需要改这两个方法,需要把onPrepareStatement中的返回值改一下,改成返回当前的SQL语句,参数中就是传入的执行的SQL语句,我们直接返回就可以打印出该语句。

而在onSave中,看名字就可以知道是在保存的时候进行调用的。我们可以进行一系列保存前的工作。

相信大家看参数名称就可以看明白了吧。

Serializable是指序列号的参数,在这里是指跟数据库ID进行映射的属性

Object[]这是一系列的状态,暂时没怎么用到,以后用到再研究,但API中说明了,不管用何种方式修改了这个数组中的值,这个onSave方法必须返回true。

String[]是指属性的名称

而Type[]也就是相应属性的类型。

1)这个Interceptor可以在保存数据库前和后做一些相应的操作。比如想对数据进行修改,添加前缀或后缀的,都可以用它来实现,下面我们来看一下。

public boolean onSave(Object arg0, Serializable arg1, Object[] arg2,
		String[] arg3, Type[] arg4) throws CallbackException {
	if (arg0 instanceof User) {
		System.out.println("User to be saved=>"+((User)arg0).getName());
	}
	//我们在这里添加123作为名字的前缀
	User user = (User)arg0;
	user.setName("123"+user.getName());
	return false;
}

   我们看一下测试方法:

public static void main(String[] args) {

	Configuration cfg = new Configuration().configure();
	SessionFactory sessionFactory = cfg.buildSessionFactory();
	Interceptor interceptor = new MyInteceptor();
	Session session = sessionFactory.openSession(interceptor);
		
	User user = new User();
	user.setName("shun");
		
	Transaction tx = session.beginTransaction();
	session.save(user);
		
	tx.commit();
	session.close();
		
}

  很简单,我们只是进行了简单的保存而已。这里就没给出映射文件和实体类,大家随便弄个试一下就行。

运行它,我们可以看到:

User to be saved=>shun
Hibernate: insert into USER (USER_NAME, age) values (?, ?)
Hibernate: update USER set USER_NAME=?, age=? where USER_ID=?

  它会在最后进行更新姓名和年龄的操作,主要是因为我们在onSave方法中进行了修改。

  我们看到数据库中的值已经修改为有123前缀的了。

2)同样道理,我们可以在加载时修改属性的值:

public boolean onLoad(Object arg0, Serializable arg1, Object[] arg2,
		String[] arg3, Type[] arg4) throws CallbackException {
		
	if (arg0 instanceof User) {
		System.out.println("User to be loaded=>"+(arg2[0]+":"+arg2[1]));
	}
	User user = (User)arg0;
	//判断哪个属性是name
	for (int i = 0; i < arg3.length; i ++){
		if (arg3[i].equals("name")){
			user.setName(((String)arg2[i]).replace("123",""));
			arg2[i] = ((String)arg2[i]).replace("123","");
		}
	}
	return false;
}

  加载时修改属性的值是写在onLoad方法内。

这里的arg0就是我们的User对象,这里它还没有值,这个方法在load方法之后才进行调用,所以我们此时对user进行操作已经是于事无补了,而且我们这里的user.setName是没用的操作。主要在:

arg2[i] = ((String)arg2[i]).replace("123","");

   这句代码改变了返回的属性的值,那么我们在程序中拿到的user对象中的值也会改变,我们运行测试方法看看:

public static void main(String[] args) {

	Configuration cfg = new Configuration().configure();
	SessionFactory sessionFactory = cfg.buildSessionFactory();
	Interceptor interceptor = new MyInteceptor();
	Session session = sessionFactory.openSession(interceptor);
		
	User user = (User)session.load(User.class,new Long(39));
		
	System.out.println("User name:"+user.getName());
	session.close();
		
}

  看结果,我们得到了:

Hibernate: select user0_.USER_ID as USER1_0_0_, user0_.USER_NAME as USER2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=?
User to be loaded=>123shun:0
User name:shun

  我们已经把原来的123给去掉了,在真正加载后进行了相关的处理,不过这个并不是真正加载前的处理,有点投机的嫌疑。但也不失为一个考虑的方案。Interceptor也许用得最多的还是在日志的相关处理上,比如我们需要对每次操作都进行相应的日志记录,那么Interceptor是一个很好的选择。

猜你喜欢

转载自cxshun.iteye.com/blog/1070937