这里使用lombok,简化代码。
分为两种关系,是一对一主键关联,一对一外键关联
一对一主键关联:这里使用用户和用户详情:
@Entity
@Table(name="tb_user")
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
@OneToOne(cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn
private UserDetail detail;
}
@Data
@Entity
@Table(name = "tb_detail")
public class UserDetail {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String nickname;
}
@OneToOne表示一个多对一的映射,该注解标注的属性通常是数据库表的外键
optional:是否允许该字段为null,该属性应该根据数据库表的外键约束来确定,默认为true
fetch:表示抓取策略,默认为FetchType.EAGER ,有 EAGER(急记载,立即记载)和LAZY(懒加载)。
cascade:表示默认的级联操作策略,可以指定为ALL(全部),PERSIST(级联保存),MERGE(级联跟新),REFRESH(级联刷新)和REMOVE(级联删除)中的若干组合,默认为无级联操作
targetEntity:表示该属性关联的实体类型.该属性通常不必指定,ORM框架根据属性类型自动判断targetEntity.
一对一外检关联:
只需要将@PrimaryKeyJoinColumn 变为@JoinColmn("外键字段名")
@JoinColmn 是用来外键的声明的,可以指定外键的字段名称。
一个用户对应多个收货地址,用户类里存在地址的list,地址里不存在用户的类。
@Entity
@Table(name="tb_user")
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
@OneToMany()
@JoinCloumn("u_id")
private List addresses;
}
Address类
@Entity
@Table(name="tb_address")
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String province;
private String city;
private User user;
}
在收货地址里不需要进行任何操作。只需要把按照正常配置即可。
地址类中存在User 属性,User里没有地址的集合。
这里一多个收货地址对应一个用户为例:
用户类:
@Entity
@Table(name="tb_user")
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
}
地址类:
@Entity
@Table(name="tb_address")
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String province;
private String city;
@ManyToOne
@JoinColumn(name = "u_id")
private User user;
}
一对多双向:
用户类里有地址的集合,地址类里有用户的实例
用户类:
@Entity
@Table(name="tb_user")
@JsonIgnoreProperties(value= {"addresses"})
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
@OneToMany()
private List addresses;
}
地址类:
@Data
@Entity
@Table(name="tb_address")
@JsonIgnoreProperties({"user"})
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String province;
private String city;
@ManyToOne
@JoinColumn(name = "u_id")
private User user;
}
加这个注解@JsonIgnoreProperties({"user"})的目的是为了查询的时候不会循环调用,造成堆栈溢出
用户和角色:
用户类:
@Entity
@Table(name="tb_user")
@JsonIgnoreProperties(value= {"addresses"})
@Data
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
@ManyToMany()
@JoinTable(name="tb_user_role",joinColumns=@JoinColumn(name="u_id"),inverseJoinColumns=@JoinColumn(name="r_id"))
List roles ;
}
角色类:
@Data
@Entity
@Table(name="tb_role")
public class Role {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@Column(name="role_name")
private String roleName;
}
使用@JoinTable注解来说明中间表,name只中间表的表名,joinColumns只当前实体在中间表的字段,inverserJoinCloumns指关联的另外一个实体在中间表的字段名。
在双向关系中,可以使用一的一方的注解中的属性mappedBy来声明关系是由谁来维护的。且声明了这个属性,@JoinColumn和@JoinTable就不能使用了
首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@manyToMany中,不能够用在@manyToOne中;
第二,这个注解看网上的意思可以简单地理解为:这个注解用在主表的一方,就是被引用的一方;
第三,这个注解是与@JoinColumn这个注解是互斥的,因为@JoinColumn这个注解使用在拥有外键的表的一方,就是从表的一方。
第四,这个注解的属性值是:指向另外一个类中定义的一个属性,这个属性的类型是当前这个类;有点绕,有点晕,是的;就是说它的属性值指向的是:与之关联类中定义的指向本类的一个属性!