http://kongtong2004.blog.163.com/blog/static/42999512007112234439912/
在说序列化之前先要了解一下持久化和解耦的概念。
何谓“解耦”
解耦就是降低系统的耦合度,使系统更加健壮、更加灵活。
MVC的基本原理和方法:将显示层与业务逻辑层解耦。但是业务逻辑层中业务处理逻辑和数据存取逻辑是混杂在一起的。
假如要换数据库产品或者运行环境,修改的代价也非常高,代价的原因就是没有将业务逻辑和数据逻辑解耦。
将这些复杂的业务逻辑和数据逻辑分离,以将系统的紧耦合关系转化为松耦合关系(即解耦合),是降低系统耦合度迫切要做的,也是持久化要做的工作。
另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。
所以为了解决这一困难,就出现 ORM(Object Relational Mapping)对象与数据之间的映射技术。
何谓“持久化”
持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
何谓“持久层”
持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。
何谓“对象数据映射(ORM)”
ORM-Object/Relational Mapper,即“对象-关系型数据映射组件”。对于O/R,即 Object(对象)和 Relational(关系型数据),表示必须同时使用面向对象和关系型数据进行开发。
设计业务逻辑代码的时候完全不需要考虑数据库JDBC的那些千篇一律的操作,只需要交给持久层处理就可以了。
流行的 ORM 产品
持久层框架的实现,常见的有Apache OJB 、Cayenne 、Jaxor 、Hibernate 、iBatis 、jRelationalFramework 、mirage 、SMYLE、TopLink(TopLink 是 Oracle 的商业产品,要钱的,其他均为开源项目)
除了ORM 技术,还有以下几种持久化技术:
主动域对象模式、JDO 模式、CMP 模式(CMP 负责持久化实体 EJB 组件,而 ORM 负责持久化 POJO)
只有忽视数据库为一种具体实现技术,系统才有可能完全迈向OO,至于数据库性能调优等特定功能都可交由ORM工具实现。
持久化(Persistence)与序列化(Serialization)
它们相似的地方都是企图将对象和其他东西进行转化,不同之处在于持久化是希望能把它持久保存起来并在需要的时候再得到它,而序列化关心的焦点则是如何把对象变为字节流,实质上从实用角度上来讲,两者有很大程度的相互覆盖,序列化机制是将类的值转化为一个一般的(即连续的)字节流,然后将该流写到磁盘文件或任何其他流化目标上的一个过程,这本身也可以称之为持久化。
何谓“序列化”
序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机。
java.io包有两个序列化对象的类
ObjectOutputStream负责将对象写入字节流,ObjectInputStream从字节流重构对象。
ObjectOutputStream类扩展DataOutput接口。
writeObject()方法是最重要的方法,用于对象序列化。如果对象包含其他对象的引用,则writeObject()方法递归序列化这些对象。每个ObjectOutputStream维护序列化的对象引用表,防止发送同一对象的多个拷贝。
ObjectInputStream类扩展DataInput接口。
readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回流中下一个Object。对象字节流并不传输类的字节码,而是包括类名及其签名。readObject()收到对象时,JVM装入头中指定的类。如果找不到这个类,则readObject()抛出ClassNotFoundException。
定制序列化过程
序列化通常可以自动完成,但有时可能要对这个过程进行控制。将数据成员声明为transient或static后,序列化过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。
使用writeObject()与readObject()方法时,还要注意按写入的顺序读取这些数据成员。
完全定制序列化过程
如果一个类要完全负责自己的序列化,则实现Externalizable接口而不是Serializable接口。
Externalizable接口定义包括两个方法writeExternal()与readExternal()。
利用这些方法可以控制对象数据成员如何写入字节流。
声明类实现Externalizable接口会有重大的安全风险。