JPA一对多、多对多理解和配置小记

文章详细阐述了JPA中的一对多关系,包括单向一对多和双向一对多的实现方式,强调了急加载和懒加载的区别。在双向一对多关系中,关系维护方需添加mappedBy属性。同时,介绍了多对多关系的处理,特别是在需要生成中间表的情况。文章还提到在数据管理中通常使用软删除策略。
摘要由CSDN通过智能技术生成

一、单向一对多

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;

四、一些注意点

  1. 哪一方有mappedBy,哪一方就是关系的被维护方。

  1. 关系的维护端和关系的被维护端在数据的更新和删除时起作用。

  1. 我们一般不会物理删除一条数据,只会更改标记来改变数据状态,也就是软删除。

  1. 如果单向多对多关系理不清楚直接全部设置成双向多对多也行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值