在春季访问多对多关系

时间:2019-10-06 18:20:58

标签: spring hibernate spring-boot jpa spring-data-jpa

我有一个叫Tag的班级:

@Entity
@Table(name = "tags")
public class Tag {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
            },
            mappedBy = "tags")
    private Set<Post> posts = new HashSet<>();

    ...
}

还有一个名为Post

的类
@Entity
@Table(name = "posts")
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
            })
    @JoinTable(name = "post_tags",
            joinColumns = { @JoinColumn(name = "post_id") },
            inverseJoinColumns = { @JoinColumn(name = "tag_id") })
    private Set<Tag> tags = new HashSet<>();


        ...
}

它将创建另一个名为post_tags的表。

由于该表与存储库不相似,我如何编写Controller来访问该表?

是否有更简便的方法来实现 ManyToMany 关系?

我的pom.xml

2 个答案:

答案 0 :(得分:1)

您不需要手动访问该关系表。您可以加载所有Tag实体,然后加载所有引用的Post实体。

关系表由您的ORM框架管理员严格管理。

但是,如果您仍然想访问关系表,则可以在Spring Data JPA存储库中使用本机查询,例如

@Query(value="select post_id, tag_id from post_tags", nativeQuery=true)
List<PostTag> loadPostTags();

PostTag类不是受jpa管理的实体,必须与返回表的结构匹配:

public class PostTag {
 private long postId;
 private long tagId;
 // getter, setter
}

答案 1 :(得分:0)

使用这种方式

@Entity
@Table(name = "tags")
public class Tag {

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

   @ManyToMany(cascade = CascadeType.ALL)
   @JoinTable(name = "post_tags",
        joinColumns = { @JoinColumn(name = "id") },
        inverseJoinColumns = { @JoinColumn(name = "post_id") })
   private Set<Post> posts = new HashSet<>();

...
}

@Entity
@Table(name = "posts")
public class Post {
   @Id
   @Column(name = "post_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long postId;
    ...
}