做的项目中要用到日志功能,记录重要数据增删改,以提供后台动态数据恢复功能,在数据库中建立一个表四个字段:
id:标识(long)、action:增删改类别(String 或 int)、olddata与newdata分别记录增删改前后的数据类型为blob、optime记录操作时间
项目持久层用了Hibernate所以数据库中所有条目都是以JavaBean形式出现,JavaBean扩展了Serializable可以实现对象的序列化,现在问题就是怎样保存JavaBean序列化的结果到数据库,并且可以逆向反序列化为实例。
因为刚接触Java对列的概念不是很清楚,所以在序列化上遇到了问题,首先是如何不通过临时文件取得对象序列化的结果,网上的例子大多是对文件流的操作,用来保存图片
综合网上的多个例子以及从JDK中查询的结果,总结出以下过程:
1、还是对流的操作,不过不是文件流而是字节流,利用ByteArrayOutputStream创建
2、通过new出来ByteArrayOutputStream作为参数创建ObjectOutputStream
3、调用ObjectOutputStream的writeObject将任意JavaBean序列化为字节流
//以上是序列化过程,实际上使用不同的XStream就可以把JavaBean序列化到不同的流中
4、通过调用ByteArrayOutputStream的toByteArray可以获得byte数组
//这是取中间值,相当于文件流操作时利用文件名打开一个文件流,文件名也是一个中间值
5、将得到的byte数组作为参数用ByteArrayInputStream打开一个输入流
6、调用静态方法Hibernate.createBlob(),以输入流为参数获取Blob
7、此后可将该Blob设置为接收Bean的属性保存到数据库中
//以上完成将序列化的结果存储到数据库
8、利用Hibernate的API的到数据库中的Blob很容易,然后调用Blob的getBinaryStream可获取输入流,将此流作为ObjectInputStream,调用readObject可得到序列化前的实例
代码:
//序列化
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(new User("cfgxy"));
//保存到数据库,sessionFactory是Hibernate中SessionFactory的一个实例
Session session=sessionFactory.createSession();
Transaction tx =session.openTransaction();
ByteArrayInputStream bis=new ByteArrayInputStream(bos.getByteArray());
session.save(new Logs(null,"INSERT",null,Hibernate.createBlob(bis)));
tx.commit();
session.close();
//从数据库读取,假设传来的参数id为数据库主键的值
Session session=sessionFactory.createSession();
Logs log=(Logs)session.load(Logs.class,id);
ObjectInputStream ois=new ObjectInputStream(log.getNewData().getBinaryStream());
return (User)ois.readObject();
//代码中均未对异常进行捕捉,实际运用中要捕捉异常
文章来源:
http://x-spirit.spaces.live.com/Blog/cns!CC0B04AE126337C0!818.entry