java—如何在SpringDataJPA和SpringBootWithJoin中添加计数字段

8ljdwjyq  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(221)

我在使用spring boot和spring数据的rest库项目中工作。我有一本实体书,里面有一堆书的副本。

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String isbn;
    @NotNull
    private String title;

    @JsonIgnore
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<BookCopy> copyList = new ArrayList<>();

...

@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
public class BookCopy {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String barcode;
    private String editor;
    private boolean available = true;

    @ManyToOne(fetch = FetchType.LAZY)
    private Book book;
...

我想执行一个请求,给我所有的书和可用的副本数量。我可以在标准sql中执行它:

select book.*, count(book_copy.id) as nb_copies from book
inner join book_copy on book.id = book_copy.book_id
where book.title like '%:title%' 
and book_copy.available = true
group by book.id

但我没办法让它在我的项目中发挥作用。我以为我可以用jpql来实现,但是当我尝试加入实体bookcopy时,intellij没有进行任何自动完成,这让我怀疑存在配置问题。如果我尝试“在控制台中运行查询”,它会告诉我“找不到运行程序”,即使我在intellij中设置了数据库。我也尝试过使用原生查询,但也不起作用。
我设法得到了一个结果,但我认为用了一个错误的方法:

@Override
    public List<Book> findByTitle(String title) {
        List<Book> bookList = bookRepository.findByTitleLike("%"+title+"%");
        for(Book book:bookList){
            book.setCopyList(bookCopyRepository.findAllInBookWhereAvailable(book.getId(), true));
        }
        return bookList;
    }

它将为每本书启动一个查询以获取复制列表。所以我没什么主意了,也没什么好消息。谢谢!

lztngnrs

lztngnrs1#

以下jpql应返回与本机sql查询相同的数据集:

select b, count(c) from Book b
join b.copyList c
where b.title like :title and c.available
group by b

java代码:

String title = ...;
        final List result = em.createQuery("select b, count(c) from Book b" +
                " join b.copyList c " +
                " where b.title like :title and c.available " +
                " group by b ")
                .setParameter("title", title)
                .getResultList();
        for (Object res : result) {
            Object[]  row = (Object[]) res;
            System.out.println("Book: " + row[0]);
            System.out.println("BookCopy CNT: " + row[1]);
        }

相关问题