Найти родительский элемент, выполнив поиск дочернего/Spring boot JPA + PostgresSQL

Я пытаюсь выяснить, как найти и вернуть все книги, связанные с конкретным именем автора.

{
    "bookId": 5,
    "bookName": "test2",
    "publishYear": 2022,
    "publisher": "test2",
    "authors": [
        {
            "id": 5,
            "name": "Heny",
            "surname": "Blakc"
        },
        {
            "id": 6,
            "name": "Garyy",
            "surname": "Harrys"
        }
    ]
}

Я хочу вернуть все книги, автором которых является Гэри.

Я использую аннотацию Spring Boot + Postgres SQL OneToMany.

Был бы признателен за любые предложения.

АвторКонтроллер:

package com.example.demo.controller;


import com.example.demo.entity.AuthorEntity;
import com.example.demo.repository.AuthorRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/author")
public class AuthorController {
    @Autowired
    AuthorRepository authorRepository;

    @GetMapping("/all")
    public List<AuthorEntity> author(){
        return authorRepository.findAll();
    }
    @PostMapping("/create")
    public AuthorEntity createAuthor(@RequestBody AuthorEntity author){
        AuthorEntity savedAuthor = authorRepository.save(author);
        return savedAuthor;
    }
    @GetMapping("/find/{author}")
    public List<AuthorEntity> findAuthor(@PathVariable(value = "author") String name){
        return authorRepository.findByName(name);
    }

}

Букконтроллер:

package com.example.demo.controller;


import com.example.demo.entity.BookEntity;
import com.example.demo.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@RestController
@RequestMapping("/book")
public class BookController {


    @Autowired
    private BookRepository bookRepository;




    @GetMapping("/all")
    public List<BookEntity> getAllBooks(){
        List<BookEntity> allBookList = bookRepository.findAll();

        return allBookList;
    }

    @GetMapping("/findBook/{name}")
    public List<BookEntity> getBookByName(@PathVariable(value = "name")String bookName)
    {
        return bookRepository.findByBookName(bookName);
    }

    @GetMapping("/year/{year}")
    public List<BookEntity> getBookByYear(@PathVariable(value = "year")Integer year)
    {
        return bookRepository.findByPublishYear(year);
    }
    @GetMapping("/publisher/{publisher}")
    public List<BookEntity> getBookByPublisher(@PathVariable(value = "publisher")String publisher)
    {
        return bookRepository.findByPublisher(publisher);
    }

    @PostMapping("/create-book")
    public BookEntity createBook (@RequestBody BookEntity book){
        BookEntity savedBook = bookRepository.save(book);

        return savedBook;
    }


}

АвторСущность:

package com.example.demo.entity;

import javax.persistence.*;

@Entity
@Table(name = "authors")
public class AuthorEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "name", nullable = false)
    private String name;
    @Column(name = "surname",nullable = false)
    private String surname;

    @ManyToOne(fetch =FetchType.LAZY)
    private BookEntity books;



    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    @Override
    public String toString() {
        return "AuthorEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", surname='" + surname + '\'' +
                ", books=" + books +
                '}';
    }

}

BookEntity:

package com.example.demo.entity;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "books")
public class BookEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Integer bookId;

    @Column(name = "book_name", nullable = false)
    private String bookName;

    @Column(name = "publish_year",nullable = false)
    private Integer publishYear;

    @Column(name = "publisher",nullable = false)
    private String publisher;

    @OneToMany(targetEntity = AuthorEntity.class, cascade = CascadeType.ALL)
    private List<AuthorEntity> authors;


    public List<AuthorEntity> getAuthors() {
        return authors;
    }

    public void setAuthors(List<AuthorEntity> authors) {
        this.authors = authors;
    }

    public Integer getBookId() {
        return bookId;
    }

    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public Integer getPublishYear() {
        return publishYear;
    }

    public void setPublishYear(Integer publishYear) {
        this.publishYear = publishYear;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    @Override
    public String toString() {
        return "BookEntity{" +
                "bookId=" + bookId +
                ", bookName='" + bookName + '\'' +
                ", publishYear=" + publishYear +
                ", publisher='" + publisher + '\'' +
                ", authors=" + authors +
                '}';
    }
}

АвторРепозиторий:

package com.example.demo.repository;

import com.example.demo.entity.AuthorEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface AuthorRepository extends JpaRepository<AuthorEntity, Integer> {
    List<AuthorEntity> findByName(String name);
}

КнигаРепозиторий:

package com.example.demo.repository;

import com.example.demo.entity.BookEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface BookRepository extends JpaRepository<BookEntity, Integer> {
    public List<BookEntity> findByBookName(String bookName);
    public List<BookEntity> findByPublishYear(Integer year);
    public List<BookEntity> findByPublisher(String publisher);
}

person Alohas    schedule 15.11.2020    source источник


Ответы (2)


Есть несколько способов сделать это, один из них - использовать forEach and filter в самом java, например

 List<BookeEntity> books = getBooks();
 books.forEach(e->{
        List<AuthorEntity> al= e.getAuthors().stream().filter(ee->ee.getName().equals("Garyy")).collect(Collectors.toList());
        e.setAuthors(al);
    });
person manikant gautam    schedule 15.11.2020
comment
Спасибо за ваше предложение, как я могу использовать, чтобы вернуть список книг? Я попытался использовать его в методе List‹BookEntity› и вернуть список книг, но этот метод возвращает только пустоту. - person Alohas; 15.11.2020
comment
я не нашел but this method return void only - person manikant gautam; 16.11.2020

Ваш дизайн базы данных был неправильным. Реальность:

  • 1 автор написал одну или несколько книг,
  • 1 книга, написанная одним или несколькими авторами.

Следовательно, вам нужна таблица автор-книга, чтобы преобразовать отношения многие-многие в 2 отношения: один-многие, многие-один.

Вы можете увидеть https://www.stat.auckland.ac.nz/%7Epaul/ItDT/HTML/node42.html section 5.6.3.2 Отношения

person Do Nhu Vy    schedule 15.11.2020