springboot jpa外键 (user role)双向多对多@ManyToMany(原创)

多个用户可能有多个角色,多个角色可能有多个用户。所以这种情况下就使用双向@ManyToMany进行关联(单项也可以,根据业务需求)

jpa会自动生成中间表,java的entity代码中只需要User类和Role类,无需创建中间表user_role类(sql建表语句中可以手动创建该中间表,不手动创建jpa系统也会帮忙自动创建)

注意:

不能用lombok的@EqualsAndHashCode和@ToString,否则死循环内存溢出

一、表结构

User表:

package com.cmit.oag.backend.entity.common;


@Entity
@Getter
@Setter
//@EqualsAndHashCode//不能用@EqualsAndHashCode和@ToString,否则死循环内存溢出
@Table(name = "user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "昵称不能为空")
    @Column(name = "user_name")
    private String userName;

    @NotBlank(message = "密码不能为空")
    @Column(name = "password")
    private String password;

    @Column(name = "status")
    private Integer status;

//    @JsonIgnoreProperties("users")
    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})//建议MERGE
    @JoinTable(name = "user_role", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<Role> roles;

}

Role表:

package com.cmit.oag.backend.entity.common;


@Entity
@Getter
@Setter
//@EqualsAndHashCode//不能用@EqualsAndHashCode和@ToString,否则死循环内存溢出
@Table(name = "role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "status")
    private Integer status;

    @Column(name = "description")
    private String description;

//    @JsonIgnoreProperties(value = { "roles" })
    @JsonIgnore
    @ManyToMany(mappedBy = "roles",fetch = FetchType.EAGER, cascade = {CascadeType.MERGE}) //建议MERGE//mappedBy对方配置关系的属性名称,表示由对方来维护中间表关系
    private Set<User> users = new HashSet<>();

}

sql:

create table user_role
(
    id          bigint(20) primary key AUTO_INCREMENT,
    user_id     bigint(20) NOT NULL,
    role_id     bigint(20) NOT NULL
# 这里外键可以不用设置,jpa代码中加以@ManyToMany控制就行了
#     CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
#     CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

二、cascade = {CascadeType.MERGE}

重要的事情说三遍:

建议使用cascade = {CascadeType.MERGE}
建议使用cascade = {CascadeType.MERGE}
建议使用cascade = {CascadeType.MERGE}

而不是{CascadeType.ALL}!!

务必参看https://blog.csdn.net/HD243608836/article/details/116137170

三、有个疑问:

双向@ManyToMany时,查询user的时候,role中包含着user,user中又包含着role...如此无限循环为什么jvm内存没有溢出???还请路过的大神评论区帮忙讲解一下。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用SpringBootJPA进行多对多查询时,可以按照以下步骤进行操作: 1. 首先,要确保项目中已经引入了所需的依赖,包括spring-boot-starter-data-jpa和相关数据库的依赖(例如h2数据库)。 2. 然后,在实体类中定义多对多的关系。假设我们有两个实体类:User和Role,它们之间是多对多的关系。可以使用@ManyToMany注解来实现这种关系。在User实体类中,使用@ManyToMany注解将User与Role关联起来,而在Role实体类中,使用@ManyToMany注解将RoleUser关联起来。 3. 接下来,需要在数据库中创建适当的来存储多对多的关系。使用JPA的自动建功能,可以根据实体类的定义自动生成相应的结构。 4. 对于多对多查询,可以使用JPA提供的方法来进行操作。例如,可以在UserRepository中定义一个方法,使用@Query注解来编写自定义的查询语句,从而实现多对多的查询操作。 5. 最后,可以在Controller层调用相应的Service方法,将查询结果返回给前端。 综上所述,使用SpringBootJPA进行多对多查询的步骤包括引入所需的依赖、定义实体类的多对多关系、创建数据库、编写查询方法和调用查询方法。通过这些步骤,可以实现多对多查询的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot JPA实现查询多值](https://download.csdn.net/download/weixin_38599430/12756496)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [spring data jpa关联查询(一对一、一对多、多对多)](https://blog.csdn.net/WGH100817/article/details/101720340)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值