一、单向一对多
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "banner")
public class Banner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 16)
private String name;
private String description;
private String img;
private String title;
@OneToMany(fetch = FetchType.LAZY) // fetch设置懒加载还是急加载,默认懒加载
@JoinColumn(name = "bannerId")
private List<BannerItem> items;
}
import javax.persistence.*;
@Entity
@Table(name = "banner_item")
public class BannerItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String img;
private String keyword;
private Short type;
private String name;
private Long bannerId;
}
急加载与懒加载:急加载会一次性执行多条语句,将关联表的数据也查询出来,懒加载只在读取相关数据时才执行关联表查询。
二、双向一对多
一对多关系中存在三种情况,正向一对多、反向一对多、双向一对多。在双向一对多关系中,多方为关系维护方,一方为关系被维护方,此时,JoinColumn应该标注在关系维护方,也就是多方。
双向多对多关系举例:
import java.util.List;
import javax.persistence.*;
@Entity
@Table(name = "banner")
public class Banner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 16)
private String name;
// Transient注解标识字段不做持久化
// @Transient
private String description;
private String img;
private String title;
@OneToMany(mappedBy = "banner")
// 取消物理外键的第一种方法,该注解已废弃
// @org.hibernate.annotations.ForeignKey(name = "null")
private List<BannerItem> items;
}
import javax.persistence.*;
@Entity
@Table(name = "banner_item")
public class BannerItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String img;
private String keyword;
private Short type;
private String name;
// 若要显示写bannerId,则要在@JoinColumn中加上insertable = false, updatable = false,否则不能写
private Long bannerId;
@ManyToOne
@JoinColumn(name = "bannerId", insertable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
// 关闭物理外键的第二种方法
private Banner banner;
}
在双向一对多关系中,需要在 @OneToMany注解中增加属性(关系被维护方),值为多方导航属性的名字。在单向一对多关系中不需要设置该属性。
三、多对多关系
一对多关系中,不需要生成第三张表,将外键设置在多方即可,而在多对多关系中需要生成第三张表来表示两张表之间的对应关系。多对多关系也分为单向多对多和双向多对多。
import javax.persistence.*;
import java.util.List;
@Entity
public class Theme {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String title;
private String name;
@ManyToMany
//设置第三张表的名称、指定第三张表的两个外键,joinColumns是因为允许设置多外键,但不推荐
@JoinTable(name = "theme_spu",joinColumns = @JoinColumn(name="theme_id"),
inverseJoinColumns = @JoinColumn(name = "spu_id"))
private List<Spu> spuList;
}
import javax.persistence.*;
@Entity
public class Spu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String title;
private String subTitle;
}
而要实现双向多对多关系,就要让jpa知道谁是关系的维护方,谁是关系的被维护方,此时需要在Spu实体(被维护方)中加入以下代码
@ManyToMany(mappedBy = "spuList")
private List<Theme> themeList;
四、一些注意点
哪一方有mappedBy,哪一方就是关系的被维护方。
关系的维护端和关系的被维护端在数据的更新和删除时起作用。
我们一般不会物理删除一条数据,只会更改标记来改变数据状态,也就是软删除。
如果单向多对多关系理不清楚直接全部设置成双向多对多也行。
文章详细阐述了JPA中的一对多关系,包括单向一对多和双向一对多的实现方式,强调了急加载和懒加载的区别。在双向一对多关系中,关系维护方需添加mappedBy属性。同时,介绍了多对多关系的处理,特别是在需要生成中间表的情况。文章还提到在数据管理中通常使用软删除策略。

被折叠的 条评论
为什么被折叠?



