文章目录
-
- 1.前言
- 2.错误示例:
- 3.正确示例
- 4.讲解
1.前言
今天在使用 JPA 的时候发现了这样一个问题,User 表和 OrganInfo 表配置了一对一关系,连表查询的时候只能够查到表 User 对象实体的数据,而 OrganInfo 对象实体为空,原因请看下面讲解,我设置的是 User 到 OrganInfo 的单项关系,如果想要设置双向关系,在 OrganInfo 实体类中添加关系即可
2.错误示例:
在 User.java中设置对应 OrganInfo 的关系
private static final long serialVersionUID = -1326615142912926353L;
@Id
@Column(name = "user_id")
private String userId;
@Column(name = "pwd")
private String pwd;
@Column(name = "fullname")
private String fullName;
@Column(name = "sex")
private String sex;
@Column(name = "age")
private Integer age;
@Column(name = "tel")
private String tel;
@Column(name = "status")
private Integer status;
@Column(name = "image_id")
private String imageId;
// User-OrganInfo
@OneToOne(fetch = FetchType.EAGER) // EAGER,那么表示取出这条数据时,它关联的数据也同时取出放入内存中
@JoinColumn(name = "user_id", referencedColumnName = "user_id",
insertable = false, updatable = false)
private OrganInfo organInfo;
// Get Set 省略
OrganInfo 实体类中字段如下(主要看主键是谁)
public class OrganInfo implements Serializable {
private static final long serialVersionUID = -1326615142912926353L;
@Column(name = "user_id", nullable = false)
private String userId;
@Id
@Column(name = "organ_id", nullable = false)
private String organId;
@Column(name = "organ_name")
private String organName;
@Column(name = "organ_introduce")
private String organIntroduce;
@Column(name = "licence_id")
private String licenceId;
@Column(name = "image_id")
private String imageId;
}
连表查询时就会造成空值的现象,如下图:

原因是什么呢?
3.正确示例
修改 OrganInfo 实体类中的主键为 userId , 对应数据库中的主键也要修改
public class OrganInfo implements Serializable {
private static final long serialVersionUID = -1326615142912926353L;
@Id
@Column(name = "user_id", nullable = false)
private String userId;
@Column(name = "organ_id", nullable = false)
private String organId;
@Column(name = "organ_name")
private String organName;
@Column(name = "organ_introduce")
private String organIntroduce;
@Column(name = "licence_id")
private String licenceId;
@Column(name = "image_id")
private String imageId;
}
数据显示正常
4.讲解
// User-OrganInfo
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", referencedColumnName = "user_id",
insertable = false, updatable = false)
private OrganInfo organInfo;
name: 外键字段名称
referencedColumnName: 参照的主表的主键名称
因为主表要通过主键来控制数据的唯一性,而从表也要控制数据的唯一性,才能称得上为一对一
上面错误的例子中,主表通过 userId 来控制数据的唯一性,而从表的外键是 userId ,那么两个表关联起来的时候,从表的数据可以不唯一,比如:
主表:userId: 123
从表:organId: zhongShan userId: 123
主表:userId: 123
从表:organId: huanNan userId: 123
(其他数据项省略)
这种就属于一对多关系了,根本不是一对一
如果将从表的主键换为 userId ,也为外键,那么就可以保证从表数据的唯一性,即一对一,如:
主表:userId:123
从表:userId:123 organId: 中山大学
主表:userId:222
从表:userId:222 organId: 华南理工大学
(其他数据项省略)