@OneToOne
, 表示一对一的映射关系,比如一个账号对应一个用户,一个实体用来描述账号的信息(账号,密码,账号是否可用,账号对应的角色等),另外一个实体用来描述用户的信息(昵称,年龄,性别,国籍等)。
该注解有六个属性:
public @interface OneToOne {
java.lang.Class targetEntity() default void.class;
javax.persistence.CascadeType[] cascade() default {};
javax.persistence.FetchType fetch() default javax.persistence.FetchType.EAGER;
boolean optional() default true;
java.lang.String mappedBy() default "";
boolean orphanRemoval() default false;
}
targetEntity
关联目标实体类,指定类型后该属性可省略;
cascade
表示关联关系中的级联操作权限,有五种权限:
CascadeType.PERSIST CascadeType.MERGE CascadeType.REMOVE CascadeType.REFRESH CascadeType.ALL
fetch
数据加载策略,默认值为 FetchType.EAGER
:
FetchType.LAZY FetchType.EAGER
optional
表示关联关系是否必须,当该值为 true
时, one
的一方可以为 null
; mappedBy
指定映射关系由哪一方维护,一般使用在双向映射场景; orphanRemoval
孤值删除,将会删除孤立数据,外键为null的数据将被删除; 我们在使用的时候,通常为了保证表的简洁性,将主键共享,意思是用户的id和账号的id是一样的,不在表中单独存在一个字段用来描述关联关系;比如下面的例子:
首先创建一个账号实体
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import javax.persistence.*;
@Table(name = "base_account")
@Entity
@org.hibernate.annotations.Table(appliesTo = "base_account", comment = "账号信息表")
public class AccountDO {
@Id
@GenericGenerator(name="idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
@Column(name = "ACCOUNT_ID", length = 32)
private String accountId;
@Column(name = "USERNAME", columnDefinition = "VARCHAR(32) NOT NULL COMMENT '账号'")
private String username;
@Column(name = "PASSWORD", columnDefinition = "VARCHAR(128) NOT NULL COMMENT '密码'")
private String password;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH})
@PrimaryKeyJoinColumn
private UserDO userDO;
// 省略构造函数,get/set方法,toString方法等
创建一个用户信息实体
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import javax.persistence.*;
@Table(name = "base_user")
@Entity
@org.hibernate.annotations.Table(appliesTo = "base_user", comment = "用户信息表")
public class UserDO {
@Id
@GenericGenerator(name = "idGenerator", strategy = "foreign", parameters = @Parameter(name = "property", value = "accountDO"))
@GeneratedValue(generator = "idGenerator")
@Column(name = "USER_ID", length = 32)
private String userId;
@Column(name = "NICKNAME", columnDefinition = "VARCHAR(32) NOT NULL COMMENT '昵称'")
private String nickname;
@Column(name = "AGE", columnDefinition = "TINYINT DEFAULT NULL COMMENT '年龄'")
private Integer age;
@Column(name = "SEX", columnDefinition = "CHAR(2) DEFAULT NULL COMMENT '性别'")
private String sex;
@OneToOne(mappedBy = "userDO")
private AccountDO accountDO;
// 省略构造函数,get/set方法,toString方法等
用户实体的主键和账号实体的主键都使用一个生成策略,生成的 id
也一样,且在账号实体中使用 @PrimaryKeyJoinColumn
来声明在表中不建立对应的映射字段。
这里贴出源码,一个 关系映射的小例子
原创不易,感谢支持。