1. <tfoot id='9u9us'></tfoot>

        <i id='9u9us'><tr id='9u9us'><dt id='9u9us'><q id='9u9us'><span id='9u9us'><b id='9u9us'><form id='9u9us'><ins id='9u9us'></ins><ul id='9u9us'></ul><sub id='9u9us'></sub></form><legend id='9u9us'></legend><bdo id='9u9us'><pre id='9u9us'><center id='9u9us'></center></pre></bdo></b><th id='9u9us'></th></span></q></dt></tr></i><div id='9u9us'><tfoot id='9u9us'></tfoot><dl id='9u9us'><fieldset id='9u9us'></fieldset></dl></div>
          <bdo id='9u9us'></bdo><ul id='9u9us'></ul>
      1. <small id='9u9us'></small><noframes id='9u9us'>

        <legend id='9u9us'><style id='9u9us'><dir id='9u9us'><q id='9u9us'></q></dir></style></legend>
      2. 使用 @ManyToMany 可分页的 Spring Data JPA

        Spring Data JPA Pageable with @ManyToMany(使用 @ManyToMany 可分页的 Spring Data JPA)

                <tbody id='3hekp'></tbody>

              • <bdo id='3hekp'></bdo><ul id='3hekp'></ul>
              • <i id='3hekp'><tr id='3hekp'><dt id='3hekp'><q id='3hekp'><span id='3hekp'><b id='3hekp'><form id='3hekp'><ins id='3hekp'></ins><ul id='3hekp'></ul><sub id='3hekp'></sub></form><legend id='3hekp'></legend><bdo id='3hekp'><pre id='3hekp'><center id='3hekp'></center></pre></bdo></b><th id='3hekp'></th></span></q></dt></tr></i><div id='3hekp'><tfoot id='3hekp'></tfoot><dl id='3hekp'><fieldset id='3hekp'></fieldset></dl></div>
                <tfoot id='3hekp'></tfoot>
                  <legend id='3hekp'><style id='3hekp'><dir id='3hekp'><q id='3hekp'></q></dir></style></legend>
                • <small id='3hekp'></small><noframes id='3hekp'>

                • 本文介绍了使用 @ManyToMany 可分页的 Spring Data JPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有 PostTag 模型,它们具有 @manytomany 关系.

                  I have Post and Tag models which have @manytomany relationship.

                  发帖

                  @Entity
                  public class Post {
                       private long id;
                  
                       @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
                       @JoinTable(joinColumns = @JoinColumn(name = "post_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
                       private Set<Tag> tags;
                  
                       ...
                  }
                  

                  标签

                  @Entity
                  public class Tag {
                       private String name;
                  
                       @ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "tags")
                       private List<Post> posts = new ArrayList<Post>();
                  

                  我想做一个按标签名查找所有分页帖子的方法.

                  I'd like to make a method which finds all paginated posts by tag name.

                  我发现 JPQL 不支持 LIMIT.

                  I found out JPQL doesn't support LIMIT.

                  我是否必须使用 setFirstResult().setMaxResults().getResultList() 实现自己的分页逻辑?

                  Do I have to implement my own paging logic using setFirstResult().setMaxResults().getResultList()?

                  @manytomany 分页的最佳做法是什么?

                  What's the best practice for pagination of @manytomany?

                  我稍微编辑了我的问题.我编写了如下所示的代码:

                  I edited my question a bit. I wrote my codes as shown below:

                  @SuppressWarnings("unchecked")
                  public Page<Post> findByTagName(String tagName, Pageable pageable) {
                  
                      long total = (long) em
                              .createQuery("SELECT COUNT(p.id) FROM Post p JOIN p.tags t WHERE t.name = :tagName")
                              .setParameter("tagName", tagName)
                              .getSingleResult();
                  
                      List<Post> content = (List<Post>) em
                              .createQuery("SELECT p FROM Post p JOIN FETCH p.tags t WHERE t.name = :tagName")
                              .setParameter("tagName", tagName)
                              .setFirstResult(pageable.getOffset())
                              .setMaxResults(pageable.getPageSize())
                              .getResultList();
                  
                      PageImpl<Post> page = new PageImpl<Post>(content, pageable, total);
                  
                      return page;
                  }
                  

                  这段代码运行良好,但我仍然想知道这是否是正确的方法.

                  This code works fine, but I'm still wondering if this is a correct way.

                  谢谢.

                  推荐答案

                  使用页面和 @ManyToMany 映射是一项非常简单的任务.

                  Working with pages and the @ManyToMany mapping is a really straightforward task.

                  首先这里是和你类似的模型(基本上只添加了 @Id@GeneratedValue 注释来获取生成的数据库标识符).

                  First here are models similar to yours (basically only added @Id and @GeneratedValue annotations to get generated database identifiers).

                  发布实体:

                  package com.example.model;
                  
                  import java.util.HashSet;
                  import java.util.Set;
                  
                  import javax.persistence.CascadeType;
                  import javax.persistence.Entity;
                  import javax.persistence.FetchType;
                  import javax.persistence.GeneratedValue;
                  import javax.persistence.Id;
                  import javax.persistence.JoinColumn;
                  import javax.persistence.JoinTable;
                  import javax.persistence.ManyToMany;
                  
                  @Entity
                  public class Post {
                  
                      @Id
                      @GeneratedValue
                      private long id;
                  
                      @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
                      @JoinTable(joinColumns = @JoinColumn(name = "post_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
                      private Set<Tag> tags = new HashSet<>();
                  
                      public Set<Tag> getTags() {
                          return tags;
                      }
                  
                  }
                  

                  标签实体:

                  package com.example.model;
                  
                  import java.util.ArrayList;
                  import java.util.List;
                  
                  import javax.persistence.CascadeType;
                  import javax.persistence.Entity;
                  import javax.persistence.FetchType;
                  import javax.persistence.GeneratedValue;
                  import javax.persistence.Id;
                  import javax.persistence.ManyToMany;
                  
                  @Entity
                  public class Tag {
                  
                      @Id
                      @GeneratedValue
                      private long id;
                  
                      private String name;
                  
                      @ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "tags")
                      private List<Post> posts = new ArrayList<Post>();
                  
                      public void setName(String name) {
                          this.name = name;
                      }
                  
                  }
                  

                  现在您需要一个 PagingAndSortingRepository 来获取帖子实体:

                  Now you need a PagingAndSortingRepository for fetching the post entities:

                  package com.example.repository;
                  
                  import java.util.Set;
                  
                  import org.springframework.data.domain.Page;
                  import org.springframework.data.domain.Pageable;
                  import org.springframework.data.repository.PagingAndSortingRepository;
                  import org.springframework.stereotype.Repository;
                  import org.springframework.transaction.annotation.Transactional;
                  
                  import com.example.model.Post;
                  
                  @Repository
                  public interface PostRepository extends PagingAndSortingRepository<Post, Long> {
                  
                      @Transactional(readOnly = true)
                      Set<Post> findByTagsName(String name);
                  
                      @Transactional(readOnly = true)
                      Page<Post> findByTagsName(String name, Pageable pageable);
                  
                  }
                  

                  使用 pagables 几乎就像编写常规 Spring Data JPA finder 方法一样简单.如果您想按指定标签实体的名称查找帖子,只需编写常规查找器,将字段名称链接起来,如 findByTags + Name.这将创建一个类似于您的 JPQL 方法 SELECT p FROM Post p JOIN FETCH p.tags t WHERE t.name = :tagName 的查询.将标签名称的参数作为唯一的方法参数传递.

                  Working with pagables is nearly as simple as writing regular Spring Data JPA finder methods. If you want to find posts by names of assigned tag entities just write the regular finder by chaining the field names like findByTags + Name. This creates a query similar to your JPQL approach SELECT p FROM Post p JOIN FETCH p.tags t WHERE t.name = :tagName. Pass the parameter for the tag name as only method parameter.

                  现在 - 如果你想添加 Pageable 支持 - 只需添加一个 Pageable 类型的参数作为第二个参数,然后将返回值转换为 Page 而不是 设置.就是这样.

                  Now - if you want to add Pageable support - just add a parameter of type Pageable as second parameter and turn the return value into a Page instead a Set. That's all.

                  至少这里有一些测试来验证代码:

                  At least here are some tests to verify the code:

                  package com.example.repository;
                  
                  import static org.hamcrest.CoreMatchers.is;
                  import static org.hamcrest.Matchers.empty;
                  import static org.hamcrest.Matchers.hasSize;
                  import static org.junit.Assert.assertThat;
                  
                  import java.util.Set;
                  
                  import javax.persistence.EntityManager;
                  import javax.persistence.PersistenceContext;
                  
                  import org.junit.Test;
                  import org.junit.runner.RunWith;
                  import org.springframework.beans.factory.annotation.Autowired;
                  import org.springframework.boot.test.context.SpringBootTest;
                  import org.springframework.data.domain.Page;
                  import org.springframework.data.domain.PageRequest;
                  import org.springframework.test.context.junit4.SpringRunner;
                  import org.springframework.transaction.annotation.Transactional;
                  
                  import com.example.model.Post;
                  import com.example.model.Tag;
                  
                  @RunWith(SpringRunner.class)
                  @Transactional
                  @SpringBootTest
                  public class PostRepositoryTests {
                  
                      @Autowired
                      private PostRepository postRepository;
                  
                      @PersistenceContext
                      private EntityManager entityManager;
                  
                      @Test
                      public void receiveMultiplePostsWithTagsByName() {
                          final String nameA = "A";
                          final String nameB = "B";
                          final String nameC = "C";
                          final String nameD = "D";
                          final String nameE = "E";
                  
                          final Tag tagA = new Tag();
                          tagA.setName(nameA);
                          final Tag tagB = new Tag();
                          tagB.setName(nameB);
                          final Tag tagC = new Tag();
                          tagC.setName(nameC);
                          final Tag tagD = new Tag();
                          tagD.setName(nameD);
                          final Tag tagE = new Tag();
                          tagE.setName(nameE);
                  
                          final Post postOne = new Post();
                          postOne.getTags().add(tagA);
                          postOne.getTags().add(tagB);
                          postRepository.save(postOne);
                  
                          final Post postTwo = new Post();
                          postTwo.getTags().add(tagA);
                          postTwo.getTags().add(tagB);
                          postTwo.getTags().add(tagE);
                          postRepository.save(postTwo);
                  
                          final Post postThree = new Post();
                          postThree.getTags().add(tagA);
                          postThree.getTags().add(tagB);
                          postThree.getTags().add(tagC);
                          postThree.getTags().add(tagE);
                          postRepository.save(postThree);
                  
                          entityManager.flush();
                          entityManager.clear();
                  
                          final Set<Post> tagsByA = postRepository.findByTagsName(nameA);
                          assertThat("Expected three hits!", tagsByA, hasSize(3));
                  
                          final Set<Post> tagsByB = postRepository.findByTagsName(nameB);
                          assertThat("Expected three hits!", tagsByB, hasSize(3));
                  
                          final Set<Post> tagsByC = postRepository.findByTagsName(nameC);
                          assertThat("Expected one hit!", tagsByC, hasSize(1));
                  
                          final Set<Post> tagsByD = postRepository.findByTagsName(nameD);
                          assertThat("Expected no hits!", tagsByD, empty());
                  
                          final Set<Post> tagsByE = postRepository.findByTagsName(nameE);
                          assertThat("Expected two hits!", tagsByE, hasSize(2));
                      }
                  
                      @Test
                      public void receiveMultiplePostsWithTagsByNamePaged() {
                          final String nameA = "A";
                  
                          final Tag tagA = new Tag();
                          tagA.setName(nameA);
                  
                          final Post postOne = new Post();
                          postOne.getTags().add(tagA);
                          postRepository.save(postOne);
                  
                          final Post postTwo = new Post();
                          postTwo.getTags().add(tagA);
                          postRepository.save(postTwo);
                  
                          final Post postThree = new Post();
                          postThree.getTags().add(tagA);
                          postRepository.save(postThree);
                  
                          final Post postFour = new Post();
                          postFour.getTags().add(tagA);
                          postRepository.save(postFour);
                  
                          final Post postFive = new Post();
                          postFive.getTags().add(tagA);
                          postRepository.save(postFive);
                  
                          entityManager.flush();
                          entityManager.clear();
                  
                          final Page<Post> tagsByAFirstPageSize2 = postRepository.findByTagsName(nameA, new PageRequest(0, 2));
                          assertThat("Expected two page items!", tagsByAFirstPageSize2.getContent(), hasSize(2));
                          assertThat("Expected five items in sum!", tagsByAFirstPageSize2.getTotalElements(), is(5L));
                          assertThat("Should be first page!", tagsByAFirstPageSize2.isFirst(), is(true));
                          assertThat("Should not be last page!", tagsByAFirstPageSize2.isLast(), is(false));
                  
                          final Page<Post> tagsBySecondPageSize2 = postRepository.findByTagsName(nameA, new PageRequest(1, 2));
                          assertThat("Expected two page items!", tagsBySecondPageSize2.getContent(), hasSize(2));
                          assertThat("Expected five items in sum!", tagsBySecondPageSize2.getTotalElements(), is(5L));
                          assertThat("Should not be first page!", tagsBySecondPageSize2.isFirst(), is(false));
                          assertThat("Should not be last page!", tagsBySecondPageSize2.isLast(), is(false));
                  
                          final Page<Post> tagsByLastPageSize2 = postRepository.findByTagsName(nameA, new PageRequest(2, 2));
                          assertThat("Expected one last page item!", tagsByLastPageSize2.getContent(), hasSize(1));
                          assertThat("Expected five items in sum!", tagsByLastPageSize2.getTotalElements(), is(5L));
                          assertThat("Should not be first page!", tagsByLastPageSize2.isFirst(), is(false));
                          assertThat("Should be last page!", tagsByLastPageSize2.isLast(), is(true));
                      }
                  
                  }
                  

                  这篇关于使用 @ManyToMany 可分页的 Spring Data JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)
                  How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)
                  Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)
                  Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)
                  How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)
                  How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)

                  • <bdo id='qqhCe'></bdo><ul id='qqhCe'></ul>

                        <tbody id='qqhCe'></tbody>
                    1. <tfoot id='qqhCe'></tfoot>

                      <small id='qqhCe'></small><noframes id='qqhCe'>

                      <i id='qqhCe'><tr id='qqhCe'><dt id='qqhCe'><q id='qqhCe'><span id='qqhCe'><b id='qqhCe'><form id='qqhCe'><ins id='qqhCe'></ins><ul id='qqhCe'></ul><sub id='qqhCe'></sub></form><legend id='qqhCe'></legend><bdo id='qqhCe'><pre id='qqhCe'><center id='qqhCe'></center></pre></bdo></b><th id='qqhCe'></th></span></q></dt></tr></i><div id='qqhCe'><tfoot id='qqhCe'></tfoot><dl id='qqhCe'><fieldset id='qqhCe'></fieldset></dl></div>
                          1. <legend id='qqhCe'><style id='qqhCe'><dir id='qqhCe'><q id='qqhCe'></q></dir></style></legend>