java中hibernate的Serializable解析

serializable是什么?

 

1
一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。

进行序列化有什么好处?

 

1
2
3
4
5
6
7
8
什么情况下需要序列化  
a)当你想把的内存中的对象写入到硬盘的时候; 
b)当你想用套接字在网络上传送对象的时候; 
c)当你想通过RMI传输对象的时候; 
再稍微解释一下:a)比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口; 
b)在进行java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。 
c)如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。 
没有人说的话能全部准确,批判性的参考。

hibernate中pojo实现Serializable的原因?

1
2
3
4
5
6
7
8
9
10
11
Object  serialization的定义:  
    Object  serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。  
     
    从对象序列化的定义可以知道,一个对象之所以要序列化,可能有以下两个原因 
     
    1 )对象要进行网络传送。比如RMI,一台机器上的对象A可以调用另一台机器上的对象B的方法M,方法中,作为参数的对象O需要传送给B,这是两台机器可能存在于异构的环境中,因此要先将对象转化为跨平台的字节序列,然后通过网络传给B,B再在自己所在的机器上恢复该对象。 
     
    2 )对象要持久化。在web开发中,session缓存,某些javaBean需要暂时持久化存储在硬盘中,因此需要序列化,存储对象的字节码。当需要的时候,再通过字节码恢复对象 
     
     
    总结:从上面可以知道,pojo实现序列化的原因是pojo对象需要持久化存储到数据库,或者被它的缓存存储在硬盘中。如果pojo存在于分布式环境中,也必须序列化。

示例解释:

 

1
2
3
4
5
public  interface  CommonDAO { 
  public  Object  get (Class clazz,Serializable id); 
  public  Serializable add( Object  o); 
这是hibernate底层的一个dao接口,add是通过hibernate向数据库save一个对象,但它为什么返回一个Serializable接口类型?是说明save的对象要实现Serrializable接口吗?如果保存的对象没有实现序列化就会抛异常吗?还有 get 方法的第二个参数是什么意思?

 

1
2
3
4
5
6
我觉得这个序列化对象是指:当前表项中的主键所对应的实体字段。 
第一个方法 public  Object get(Class clazz,Serializable id); 
显然是查找对象时所需要的表(即实体类)和id(即主键,主键可以是一个列项或多个列项)因为主键需要被hibernate进行管理以用来在session中 '备份' 或者实现远程传递等等,序列化是有必要的。 
     
至于第二个方法: public  Serializable add(Object o); 
返回值应该就是保存对象得到的序列化主键(有的对象保存完成才能知道主键的值,如含有自增字段的)。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Hibernate是Java应用和关系数据库之间的桥梁,它负责Java对象和关系数据之间的映射。Hibernate内部封装了通过JDBC访问数据库的操作,向上层应用提供了面向对象的数据访问API。在Java应用中使用Hibernate包含以下步骤。 
  
 ( 1 )创建Hibernate的配置文件。 
  
 ( 2 )创建持久化类。 
  
 ( 3 )创建对象-关系映射文件。 
  
 ( 4 )通过Hibernate API编写访问数据库的代码。 
  
 本章通过一个简单的例子helloapp应用,演示如何运用Hibernate来访问关系数据库。helloapp应用的功能非常简单:通过Hibernate保存、更新、删除、加载及查询Customer对象。图 1 显示了Hibernate在helloapp应用中所处的位置。 
   
 图 1  Hibernate在helloapp应用中所处的位置 
  
 helloapp应用既能作为独立的Java程序运行,还能作为Java Web应用运行,该应用的源代码位于配套光盘的sourcecode/chapter2/helloapp目录下。 
  
  2.1  创建Hibernate的配置文件 
  
 Hibernate从其配置文件中读取和数据库连接有关的信息,这个配置文件应该位于应用的classpath中。Hibernate的配置文件有两种形式:一种是XML格式的文件;还有一种是Java属性文件,采用 "健=值" 的形式。 
  
 下面介绍如何以Java属性文件的格式来创建Hibernate的配置文件。这种配置文件的默认文件名为hibernate.properties,例程 2 - 1 为示范代码。 
  
 例程 2 - 1  hibernate.properties 
  
 hibernate.dialect= 
 net.sf.hibernate.dialect.MySQLDialect 
 hibernate.connection.driver_class= 
 com.mysql.jdbc.Driver 
 hibernate.connection.url=jdbc:mysql: 
  //localhost:3306/SAMPLEDB 
 hibernate.connection.username=root 
 hibernate.connection.password= 1234
 hibernate.show_sql= true
  
 以上hibernate.properties文件包含了一系列属性及其属性值,Hibernate将根据这些属性来连接数据库,本例为连接MySQL数据库的配置代码。表 2 - 1 对以上hibernate.properties文件中的所有属性做了描述。 
  
 表 2 - 1  Hibernate配置文件的属性 
  
 Hibernate能够访问多种关系数据库,如MySQL、Oracle和Sybase等。尽管多数关系数据库都支持标准的SQL语言,但是它们往往还有各自的SQL方言,就像不同地区的人既能说标准的普通话,还能讲各自的方言一样。 
  
 hibernate.dialect属性用于指定被访问数据库使用的SQL方言,当Hibernate生成SQL查询语句,或者使用 native 对象标识符生成策略时,都会参考本地数据库的SQL方言。本书第 5 章(映射对象标识符)介绍了Hibernate的各种对象标识符生成策略。 
  
 在Hibernate软件包的etc目录下,有一个hibernate.properties文件,它提供了连接各种关系数据库的配置代码样例。 
  
  2.2  创建持久化类 
  
 持久化类是指其实例需要被Hibernate持久化到数据库中的类。持久化类通常都是域模型中的实体域类。持久化类符合JavaBean的规范,包含一些属性,以及与之对应的getXXX()和setXXX()方法。例程 2 - 2 定义了一个名为Customer的持久化类。 
  
 例程 2 - 2  Customer.java 
  
  package  mypack; 
  import  java.io.Serializable; 
  import  java.sql.Date; 
  import  java.sql.Timestamp; 
  
  public  class  Customer  implements  Serializable 
 { 
  private  Long id; 
  private  String name; 
  private  String email; 
  private  String password; 
  private  int  phone; 
  private  boolean  married; 
  private  String address; 
  private  char  sex; 
  private  String description; 
  private  byte [] image; 
  private  Date birthday; 
  private  Timestamp registeredTime; 
  
  public  Customer(){} 
  
  public  Long getId() 
 { 
  return  id; 
 } 
  
  public  void  setId(Long id) 
 { 
  this .id = id; 
 } 
  
  public  String getName() 
 { 
  return  name; 
 } 
  
  public  void  setName(String name) 
 { 
  this .name=name; 
 } 
  
  //此处省略email、password和phone 
 等属性的getXXX()和setXXX()方法 
 …… 
 } 
  
 持久化类符合JavaBean的规范,包含一些属性,以及与之对应的getXXX()和setXXX()方法。getXXX()和setXXX()方法必须符合特定的命名规则, "get" "set" 后面紧跟属性的名字,并且属性名的首字母为大写,例如name属性的get方法为getName(),如果把get方法写为getname()或者getNAME(),会导致Hibernate在运行时抛出以下异常: 
  
 net.sf.hibernate.PropertyNotFoundException: 
 Could not find a getter 
  for  property name in  class  mypack.Customer 
  
 如果持久化类的属性为 boolean 类型,那么它的get方法名既可以用 "get" 作为前缀,也可以用 "is" 作为前缀。例如Customer类的married属性为 boolean 类型,因此以下两种get方法是等价的: 
  
  
  public  boolean  isMarried() 
 { 
  return  married; 
 } 
  
 或者: 
  
  public  boolean  getMarried() 
 { 
  return  married; 
 } 
  
 Hibernate并不要求持久化类必须实现java.io.Serializable接口,但是对于采用分布式结构的Java应用,当Java对象在不同的进程节点之间传输时,这个对象所属的类必须实现Serializable接口,此外,在Java Web应用中,如果希望对HttpSession中存放的Java对象进行持久化,那么这个Java对象所属的类也必须实现Serializable接口。 
  
 Customer持久化类有一个id属性,用来惟一标识Customer类的每个对象。在面向对象术语中,这个id属性被称为对象标识符(OID,Object Identifier),通常它都用整数表示,当然也可以设为其他类型。如果customerA.getId().equals(customerB.getId())的结果是 true ,就表示customerA和customerB对象指的是同一个客户,它们和CUSTOMERS表中的同一条记录对应。 
  
 Hibernate要求持久化类必须提供一个不带参数的默认构造方法,在程序运行时,Hibernate运用Java反射机制,调用java.lang.reflect.Constructor.newInstance()方法来构造持久化类的实例。 
  
 如果对这个持久化类使用延迟检索策略,为了使Hibernate能够在运行时为这个持久化类创建动态代理,要求持久化类的默认构造方法的访问级别必须是 public protected 类型,而不能是 default private 类型。 
  
 在本书第 10 章(Hibernate的检索策略)介绍了Hibernate的延迟检索策略及动态代理的概念。 
  
 在Customer类中没有引入任何Hibernate API,Customer类不需要继承Hibernate的类,或实现Hibernate的接口,这提高了持久化类的独立性。如果日后要改用其他的ORM产品,比如由Hibernate改为OJB,不需要修改持久化类的代码。 
  
 本书第 1 章介绍了J2EE的持久化方案,无论是基于CMP的实体EJB,还是基于BMP的实体EJB,它们的共同特点是都必须运行在EJB容器中。而Hibernate支持的持久化类不过是普通的Java类,它们能够运行在任何一种Java环境中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值