【问题标题】:JPA @OneToMany get latest record by date from JoinJPA @OneToMany 从 Join 获取最新记录
【发布时间】:2017-11-19 07:05:11
【问题描述】:

在尝试从 Join 获取最新记录时遇到问题 我有以下课程

作者

    @Entity
    @Table(name = "author")
    public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name = "name")
    private String name;
    @OneToMany
    @JoinColumn(name = "author_id", referencedColumnName = "id")
    @OrderBy("id Desc")
    private List<Book> books;
    public int getId() {
       return id;
    }
    public void setId(int id) {
       this.id = id;
    }
    public String getName() {
       return name;
    }
    public void setName(String name) {
       this.name = name;
    }
    public List<Book> getBooks() {
       return books;
    }
    public void setBooks(List<Book> books) {
       this.books = books;
     }
    }

    @Entity
    @Table(name = "book")
    public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name = "author_id")
    private Integer authorId;
    @Column(name = "date_published")
    private Date datePublished;
    public int getId() {
        return id;
    }
    public void setId(int id) {
       this.id = id;
    }
    public Integer getAuthorId() {
       return authorId;
    }
    public void setAuthorId(Integer authorId) {
       this.authorId = authorId;
    }
    public Date getDatePublished() {
       return datePublished;
    }
    public void setDatePublished(Date datePublished) {
       this.datePublished = datePublished;
     }
    }

存储库

    @Repository
    public interface AuthorRepository extends 
    JpaRepository<Author, Long> {

         public Page<Author> findALL(int id, Pageable pageable);

    }

当前结果

    {
      "id": 1,
      "name": "James",
      "books":[
      {
         "id": 1,
         "name": "book1",
         "datePublished": '12/12/2012'

      },
      {
         "id": 1,
         "name": "book2",
         "datePublished": '01/02/2013'
      }]
    },

    {
      "id": 2,
      "name": "Tim",
      "books":[
      {
         "id": 5,
         "name": "book5",
         "datePublished": '12/12/2014'

      },{
          "id": 6,
          "name": "book6",
          "datePublished": '01/02/2015'

       }]
    }

预期结果

    {
       "id": 1,
       "name": "James",
       "books":[
       {
         "id": 1,
         "name": "book2",
         "datePublished": '01/02/2013'
       }]
   },
   {
     "id": 2,
     "name": "Tim",
     "books":[
     {
        "id": 6,
        "name": "book6",
        "datePublished": '01/02/2015'

     }]
   }

据此,作者列表连同他们各自的书籍一起返回。

问题是 JPA 如何帮助我根据出版日期从收藏中挑选出最新的书。

【问题讨论】:

  • 您能否详细说明您的问题,“JPA 如何帮助我根据出版日期仅从收藏中挑选最新书籍。”?
  • 刚刚添加了当前和预期的结果。希望这能说明一点。可能是否可以对每个作者的书籍收藏设置一个最大日期
  • 所以,基本上,您是在尝试从每个用户的图书列表中获取最新的图书(单本图书)?
  • 是的。查找所有作者及其最新书籍。请记住,存储库将根据需要进行不同的调用。只需要一个就可以归还最新一本书
  • 一个问题,为什么您的作者实体中有 JoinColumn 与图书实体具有 OneToMany 关系?你会遇到问题。 JoinColumn 用于拥有方,在这种情况下是 Books,因为作者可以拥有多本书。

标签: spring jpa spring-data-jpa


【解决方案1】:

@Seldo97 的回答是正确的,但是他错过了 Select 查询中“book”和“where”之间的空格,这会引发错误。

所以基本上应该是这样的

@OneToMany
@JoinColumn(name = "author_id", referencedColumnName = "id")
@Where(clause = "date_published = (SELECT MAX(book.date_published) " +
                                   "FROM book" +
                                   " where author_id = book.author_id)")
@OrderBy("datePublished Desc")
private List<Book> books;
  • author_id -> 基本上是指子项中的外键列名。 实体

  • date_published -> 这指的是我们想要的列 排序(在本例中为日期列名称)。

所以,上面的查询将获取最新日期的记录并将其放入列表对象中:

List<book> book;

【讨论】:

    【解决方案2】:

    我有类似的问题。另一种解决方案是使用@Where 注解:

    @OneToMany
    @JoinColumn(name = "author_id", referencedColumnName = "id")
    @Where(clause = "date_published = (SELECT MAX(book.date_published) " +
                                       "FROM book" +
                                       "where author_id = book.author_id)")
    @OrderBy("datePublished Desc")
    private List<Book> books;
    

    我在堆栈上的帖子:Get applications with their latest status only

    【讨论】:

      【解决方案3】:

      如果您使用休眠,您可以使用@JoinFormula 按日期映射最新记录来实现此目的。比如:

      @ManyToOne(fetch = FetchType.LAZY)
      @JoinFormula("(" +
          "SELECT b.id " +
          "FROM book b " +
          "WHERE b.author_id = id " +
          "ORDER BY b.date_published DESC " +
          "LIMIT 1" +
      ")")
      private Book latestBook;
      

      【讨论】:

      【解决方案4】:

      如果你想获取每个作者的最后一本书,你可以添加瞬态字段来获取它:

      @Entity
          @Table(name = "author")
          public class Author {
          .......
          @Transient 
          private Book lastBook;
      
         @PostLoad
         private void setLastBook() {
        if(books==null || books,isEmpty())
           this.lastBook=null;
        }else{
          this.lastBook=books.get(0);
        }
      }
      

      或将其一对一并使用@PostPersist 和@PostUpdate 注释的相同方法将其保存在数据库中。它将自动保存在数据库中的最后一本书

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 2023-03-27
        • 1970-01-01
        • 2021-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多