为什么一个类要实现Serializable接口?

7
@Entity
public class Husband implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne
   private Wife wife;

}

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne(mappedBy="wife")
   private Husband husband;

}
  1. Serializable是什么意思?
  2. 一个类为什么要实现Serializable接口?
  3. 为什么丈夫成员只有 @OnetoOne(mappedBy ="Wife"),而妻子成员没有 @OnetoOne(mappedBy="husband")?

因为您想要序列化该类的对象... - Neil Stockton
4个回答

13
  1. 序列化,广义上来说,是Java提供给开发者将任何对象的状态持久化到一个持久化存储区的方式。

  2. 如果开发者希望将某个编写的类的实例持久化到后端存储区,则该类需要声明为实现Serializable接口。

  3. 以上代码表示夫妻之间的一对一关系。这意味着每个妻子与一个丈夫有关联,每个丈夫也与一个妻子有关联。:-) 在上述关系中,丈夫是关系的主人[在实体-关系术语中],这就是为什么妻子说它被映射/关联到丈夫而不是反过来。这意味着丈夫识别它的妻子而不是反过来。


我喜欢这个例子,让它变得非常简单。谢谢! - Samarland
1
我仍然不明白为什么我们要在大多数实体中使用Serializable,以及何时使用? - Samarland

7

1) Serializable接口只是一个标记。它意味着对象可以被序列化,即它们可以被表示为位字符串,并从该位字符串中恢复。

例如,您的两个类都是可序列化的,因为它们可以被表示为位字符串(或常规字符串)。另一方面,表示操作系统提供的文件句柄的类无法序列化:一旦程序完成,该句柄就消失了,没有办法重新获取它。通过文件名重新打开文件不能保证有效,因为它可能已经在此期间被删除/移动/更改权限。

2) 序列化未实现Serializable接口的对象将导致抛出NotSerializableException

3) 根据文档

mappedBy
此元素仅在关联的反向(非拥有)端上指定。


3

1

我只想回答第三个问题,因为它没有完全被解释清楚。

以下是你的问题:

为什么丈夫成员单独拥有 @OnetoOne(mappedBy="Wife"),而妻子成员没有 @OnetoOne(mappedBy="husband")

首先,这里有一些错误:应该是:@OneToOne(mappedBy="wife"),而不是 Wife。请注意,mappedBy 应该跟随 Husband 类的属性 wife,而不是 Wife,也不是 Husband 类名,尽管 Husband 类是所有者。在 Hibernate文档 中说:

mappedBy 指的是所有者端关联属性的名称。

第二点需要注意的是,当我们进行数据库映射时,有两种关系:单向和双向。我们使用单向关系只有在我们只想让一个部分处理/维护这个关系,并且从另一侧来说,我们不感兴趣获取这一侧的数据。在您的示例中,如果我们只想从HusbandWife类建立单向关系,我们只想知道通过具有Husband类型对象,他的妻子是谁(通过其getWife()方法),但我们对了解一个女士的丈夫不感兴趣。
在这种情况下,我们可以编写以下代码: (请注意,在Husband类中,我们具有Wife类型的属性,但在Wife类中,我们没有Husband类型的属性)

Husband.java:

@Entity
public class Husband implements Serializable {

   ...
   @OneToOne
   //note that @JoinColumn is necessary when mapping, 
   //and although in the table you may have columns like 
   //`ID_WIFE` in table of Husband, in Java it's not a number 
   //attribute, it's an attribute of `Wife` type.
   @JoinColumn(name="idWife")
   private Wife wife;

}

Wife.java:

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   //We can omit the attribute `husband` of `Husband` type, 
   //because we are not interested in it. Or, we don't need 
   //to map in the owned side, because it's unidirectional.

}

但是,如果我们想要建立双向关系,我们必须在两个方向上进行映射,并且在拥有方的属性之前需要使用mappedBy

我们保持Husband端不变,然后更改Wife.java

Wife.java:

@Entity
public class Wife implements Serializable {

   @Id
   private int id;

   private String name;

   @OneToOne(fetch=FetchType.LAZY, mappedBy="wife")
   private Husband husband;


}

请查看此页面:https://en.wikibooks.org/wiki/Java_Persistence/OneToOne,它以易懂的方式解释了所有内容。

第三点,只需注意一下:拥有方通常是具有另一个表的外键的表的类。或者,我们只需记住:拥有者拥有所有权,因此它在其表中也具有FK。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接