赞
踩
首先明确两个端的关联关系,在java实体类定义中,含有mappedBy属性的时关系被维护端,含有关联字段的是关系维护端。
假设有实体People和Address,他们的关系是一对一,再设定People实体是关系的维护端,应有如下设计
//People.java @Entity @Table(name = "people") public class People { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id;//id @Column(name = "\"name\"", nullable = true, length = 20)//这个name加上双引号的原因是在jpa转为sql的时候会把name识别成sql关键字导致报错,反斜杠用来转义 private String name;//姓名 @OneToOne(cascade=CascadeType.ALL)//People是关系的维护端,当对People对象进行增删改时,会同时对address对象进行增删改 @JoinColumn(name = "address_id", referencedColumnName = "id")//people中的address_id字段参考address表中的id字段 private Address address;//地址 //getter and setter } //Address.java @Entity @Table(name = "address") public class Address { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id;//id @Column(name = "location", nullable = true, length = 100) private String location;//位置 @OneToOne(mappedBy = "address")//这里没有级联操作,不需要维护关系 private People people; //getter and setter }
在一对多关系中,“一”的一端是关系被维护端,它含有“多”的一端的对象集合属性,用@OneToMany注释这个属性;“多”的一端是关系维护端,它含有“一”的一端的对象属性,用@ManyToOne注释这个属性。
假设有实体User和Department,他们的关系是多对一的关系,有如下设计
//User.java @Entity @Table(name = "user") public class UserEntity { @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") @Id private String id; @Column(name = "\"name\"") private String name; @JoinColumn(name = "department_id", referencedColumnName = "id") @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, optional = false)//一般需要级联合并和刷新,具体结合业务需求,optional=false表示department不可为空 private SabDepartmentEntity department; //getter and setter } //Department.java @Entity @Table(name = "department") public class DepartmentEntity { @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") @Id private String id; @Column(name = "\"name\"") private String name; @OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL)//这里需要所有级联操作,具体可以结合业务需求 private List<SabUserEntity> users; //getter and setter }
多对多的关联关系中一般不设置级联操作,根据需求来决定任意一方为关系维护端,关系维护端的属性仍然有关联字段的声明,关系被维护端仍然有mappedBy的声明。值得注意的是,关系被维护端并不能直接删除对象,如果需要删除,需要先将其对应的关系维护端中的关系删除,比如有用户和角色,用户是关系维护端,如果要删除角色,需要先将对应的用户的角色列表中这个角色清除,才能删除角色。而关系维护端可以直接删除,假如设置了级联删除,举个例子,删除用户时也会删除角色。一般关联关系表使用的是两个外键作为双主键。
//User.java @Entity @Table(name = "user") public class userEntity { @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") @Id private String id; @Column(name = "\"name\"") private String name; @JoinTable(name = "sab_user_role_rel", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")} )//这个joinColumns的JoinColumn的name是当前实体在关联关系中的外键列,inverseJoinColumns的JoinColumn的name是对方实体在关联关系中的外键列,referencedColumnName是指该实体在本身实体中的主键列 @ManyToMany private List<SabRoleEntity> roles; //getter and setter } //Role.java @Entity @Table(name = "role") public class RoleEntity { @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") @Id private String id; @Column(name = "\"name\"") private String name; @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY) private List<SabUserEntity> users; //getter and setter }
另外附上级联操作作用的解析
jpa级联操作Cascade解析
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。