虽然平时经常用hibernate的持久化类DO,但是仅限于随手逆向工程生成相应数据库表的持久化类,然后拿来用,根本就没有深入的去了解hibernate的持久化和类的序列化的具体用法原理。闲来没事查查资料,再结合在实际应用中的体会
,感觉有必要写一写。
一、什么是序列化
对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值(
serialVersionUID)来记录自己,这个过程叫对象的串行化(Serialization)。串行化的主要任务是写出对象实例变量的数值以控制持久化对象的版本。如果该变量是另一对象的引用,则引用的对象也要串行化。这个过程是递归的。
把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。实现java.io.Serializable接口的类对象可以转换成字节流(序列化)或从字节流恢复(饭序列化),不需要在类中增加任何代码。如下图。
package nju.software.xkxt.data.dataobject;
/**
* @author typ
*
*/
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "user", catalog = "xkxtbeta")
public class UserDO implements java.io.Serializable {
private static final long serialVersionUID = 60803763950279619L;
private Integer userId;
private String name;
/** default constructor */
public UserDO() {
}
/** minimal constructor */
public UserDO(Integer userId) {
this.userId = userId;
}
/** full constructor */
public UserDO(Integer userId, String name) {
this.userId = userId;
this.name = name;
}
// Property accessors
@Id
@Column(name = "user_id", unique = true, nullable = false)
public Integer getUserId() {
return this.userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Column(name = "name", length = 45)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
上图中serialVersionUID的作用是对持久化对象的序列化的版本控制,控制各版本反序列化时是否兼容。Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
serialVersionUID 有两种生成方式:
1.Add default Serial version ID,默认为1L,比如:private static finallong serialVersionUID = 1L;
2.Add generated Serial versionID,根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: private static final longserialVersionUID = 60803763950279619L。
struts架构下的网站经常出现javax.servlet.ServletException:BeanUtils.populate错误,但是本地运行又一切正常,原因是tomcat把所有类串行化时候,不同项目间很多java类都是互相复制粘贴的,所以导致了很多类的serialVersionUID都是同一个值,所以tomcat会把不同项目的相同类名的类当作同一个类去处理,导致了这个奇怪的错误。每个项目同名的类serialVersionUID改为不一样就可以解决部署上去的网站报错问题。
二、持久化
序列化是能够实现对象的写入和写出,这样在此基础上,持久化就水到渠成了。持久化是将程序数据在持久状态和瞬时状态间转换的机制。JDBC就是一种持久化机制。文件IO也是一种持久化机制。在一定周期内保持不变就是持久化,持久化是针对时间来说的。持久化就是把内存中的对象保存到外存中,让以后能够取回。而保存和取回的过程就是经过序列化和对象io完成的。
序列化是为了解决对象的传输问题,使对象传输可以在线程之间、进程之间、内存外存之间、主机之间进行。我之所以在这里提到序列化,是因为我们可以利用序列化来辅助持久化。
未完待续......