JPA#OneToOne
无力吐槽。
一对一,一个人有一个身份证号码、一个人有一条命,类似于这一种的就是一对一的关系。
涉及到的注解两个:
OneToOne
JoinColumn(
name="当前实体对应数据库表中的字段名称,这个字段是一对一关系中对方的主键,这个字段是本表中的外键",
referencedColumnName="这是个数据库表的字段名称,字段为当前表的外键所对应的另外一张表的主键"
)
JsonIgnoreProperties(value = {"需要被忽略的字段名称,这个字段来自哪里需要通过实际情况判定"})
举一个例子:一个学生有一个桌子
@Entity @Table(name="t_student") public class Student { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private Integer id; @Column(name="name") private String name; /** * Column作用在实体的简单属性上面,简单属性就是String,Integer等类型, * 体现在数控表上面就是一个字段。 * * JoinColumn 作用在实体的复杂属性上面,复杂属性就是别的实体, * 体现在数据库表格上面就是一个外键。 * * JoinColumn.name 是当前复杂属性(此处是desk)在本实体所对应数据库表(t_student)的外键(即t_student.desk_id)。 * JoinColumn.referencedColumnName 外键(desk_id)所引用的那个表(t_desk)的主键(id)。 * * JsonIgnoreProperties.value 是在序列化本实体Student对象为JSON时,在处理复杂属性desk时候,忽略desk的student属性 * 否则将会导致desk与student实例间的相互引用产生死循环。 */ @OneToOne @JoinColumn(name="desk_id",referencedColumnName="id") @JsonIgnoreProperties(value="student") private Desk desk; @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE); } }
@Entity @Table(name="t_desk") public class Desk { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private Integer id; @Column(name="name") private String name; /** * mappedBy的取值往往是两个关联关系对应实体(此处是Student与Desk)中另外一个实体(Student)的一个属性(desk)。 * * 如何理解呢?下面是个人的理解,可能不准确。 * Desk这个类拥有id,name,student三个属性, * desk.student属性如何与student类的实例进行关联呢? * 当然是通过student的desk属性,让desk.student与student进行关联。 * 因此,此处的mappedBy应该为被注解的属性的一个属性,被注解的属性的属性应该是本实体对应数据库表的在其他表中的一个外键。 */ @JsonIgnoreProperties(value="desk") @OneToOne(mappedBy="desk") private Student student; @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE); } }
数据库表:
_
映射,无论是一对一或者是其他的映射形式,都在另外一个维度分为单向的映射,以及双向映射。其中双向映射时候,JSON序列化会产生死循环。
解决双向映射时候的json序列化死循环需要通过类似@JsonIgnoreProperties(value = {"student"})的注解来完成。
@JsonIgnoreProperties的作用是被作用的实体属性的属性如果需要被忽略(往往是死循环的原因),就用这个注解来完成。