讲到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是一个很好的选择。