Zapytanie @query w springboot - wynik z JSON

0

Cześć, mam problem z przefiltrowaniem mojego wyniku z zapytania do bazy danych w API.

Może najpierw przedstawię mój kod, a następnie wyjaśnię o co dokładnie mi chodzi.


@Entity
@Validated
public class Ksiazka {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idKsiazka;
    private int idKategoria;
    private String isbn;
    @JsonView(DoubleName.class)
    private String tytul;
    @JsonView(DoubleName.class)
    private String autor;
    private int stron;
    private String wydawnictwo;
    private int rokWydania;
    private String opis;


    public Ksiazka(){ }

    public Ksiazka(int idKsiazka, int idKategoria, String isbn, String tytul, String autor, int stron, String wydawnictwo, int rokWydania, String opis) {
        this.idKsiazka = idKsiazka;
        this.idKategoria = idKategoria;
        this.isbn = isbn;
        this.tytul = tytul;
        this.autor = autor;
        this.stron = stron;
        this.wydawnictwo = wydawnictwo;
        this.rokWydania = rokWydania;
        this.opis = opis;
    }

    public int getIdKsiazka() {
        return idKsiazka;
    }

    public void setIdKsiazka(int idKsiazka) {
        this.idKsiazka = idKsiazka;
    }

    public int getIdKategoria() {
        return idKategoria;
    }

    public void setIdKategoria(int idKategoria) {
        this.idKategoria = idKategoria;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getTytul() {
        return tytul;
    }

    public void setTytul(String tytul) {
        this.tytul = tytul;
    }

    public String getAutor() {
        return autor;
    }

    public void setAutor(String autor) {
        this.autor = autor;
    }

    public int getStron() {
        return stron;
    }

    public void setStron(int stron) {
        this.stron = stron;
    }

    public String getWydawnictwo() {
        return wydawnictwo;
    }

    public void setWydawnictwo(String wydawnictwo) {
        this.wydawnictwo = wydawnictwo;
    }

    public int getRokWydania() {
        return rokWydania;
    }

    public void setRokWydania(int rokWydania) {
        this.rokWydania = rokWydania;
    }

    public String getOpis() {
        return opis;
    }

    public void setOpis(String opis) {
        this.opis = opis;
    }
}

@RestController
@RequestMapping("/api/osoba")
public class APIController {

    @Autowired
    private KsiazkaRepo ksiazkaRepo;

    @JsonView(OnlyName.class)
    @RequestMapping(method = RequestMethod.POST, value = "/getAutor")
    public Ksiazka findAutorById(@RequestParam("id") int id){
        String autor = ksiazkaRepo.findAutorById(id);
        String title = ksiazkaRepo.findTitleById(id);
        Ksiazka ksiazka = new Ksiazka();
        ksiazka.setAutor(autor);
        ksiazka.setTytul(title);
        return ksiazka;
    }

}
@Repository
public interface KsiazkaRepo extends JpaRepository<Ksiazka, Integer> {

    @Query(value = "SELECT ksiazka.tytul, ksiazka.autor FROM IEci8d0gZc.ksiazka WHERE ksiazka.rok_wydania = :id", nativeQuery = true)
    List<String> findInfoById(@Param("id") int id); // here you

}

Zrzut bazy danych w załączniku!

Przechodząc do sedna.

Tworząc takie zapytanie dla przykładowo "rok_wydania" = 2014 dostaje wynik w takiej postaci:

[
    {
        "tytul": null,
        "autor": "Język C++. Kompendium wiedzy,Bjarne Stroustrup"
    },
    {
        "tytul": null,
        "autor": "Kali Linux. Testy penetracyjne,Joseph Muniz, Aamir Lakhani"
    },
    {
        "tytul": null,
        "autor": "Praca z zastanym kodem. Najlepsze techniki,Michael Feathers"
    },
    {
        "tytul": null,
        "autor": "Tajemnice JavaScriptu. Podręcznik ninja,John Resig, Bear Bibeault"
    },
    {
        "tytul": null,
        "autor": "Java EE 6. Tworzenie aplikacji w NetBeans 7,David R. Heffelfinger"
    },
    {
        "tytul": null,
        "autor": "Projektowanie stron internetowych. Przewodnik dla początkujących webmasterów po HTML5, CSS3 i grafice. Wydanie IV,Jennifer Niederst Robbins"
    }
]

Niby wszystko fajnie, bo wyciąga potrzebne mi dane z baz danych ale odpowiedz w JSON'ie już nie jest taka jaką bym chciał.
Jak sprawdzić żeby odpowiedź była rozdzielona na 2. W sensie żeby do miejsca "tytul" wpadał tytuł i odpowiednio dla miejsca "autor" wpadał tylko autor.
Żeby wyglądało to mniej więcej tak:

[
    {
        "tytul": "Język C++. Kompendium wiedzy",
        "autor": ",Bjarne Stroustrup"
    },
    {
        "tytul": "Kali Linux. Testy penetracyjne",
        "autor": "Joseph Muniz, Aamir Lakhani"
    },
    {
        "tytul": null,
        "autor": "Praca z zastanym kodem. Najlepsze techniki,Michael Feathers"
    },
    {
        "tytul": "Tajemnice JavaScriptu. Podręcznik ninja",
        "autor": "John Resig, Bear Bibeault"
    },
    {
        "tytul": "Java EE 6. Tworzenie aplikacji w NetBeans 7",
        "autor": "David R. Heffelfinger"
    },
    {
        "tytul": "Projektowanie stron internetowych. Przewodnik dla początkujących webmasterów po HTML5, CSS3 i grafice. Wydanie IV",
        "autor": "Jennifer Niederst Robbins"
    }
]

Z góry dziękuję wszystkim zainteresowanym tematem :)

0

Jeżeli dobrze rozumiem twoje pytanie to możesz to sobie, np. zmapować na jakąś projekcię/dto

    public interface KsiazkaDto {
        String getTytul();
        String getAutor();
    }
@Repository
public interface KsiazkaRepo extends JpaRepository<Ksiazka, Integer> {

   @Query(value = "SELECT ksiazka.tytul, ksiazka.autor FROM IEci8d0gZc.ksiazka WHERE ksiazka.rok_wydania = :id", nativeQuery = true)
   List<KsiazkaDto> findInfoById(@Param("id") int id);

}

albo bez native query (nie wiem jak to zadziała z polskimi nazwami zmiennych)

    public class KsiazkaDto {
        private String tytul;
        private String autor;

        public KsiazkaDto(String tytul, String autor) {
            this.tytul = tytul;
            this.autor = autor;
        }
        
        //getters
    }
@Repository
public interface KsiazkaRepo extends JpaRepository<Ksiazka, Integer> {

   List<KsiazkaDto> findInfoByRokWydania(int id);

}
0

a po co native query?
JpaRepository pozwala Ci dodawać customowe metody https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
W twoim przypadku będzie wyglądać coś takiego:

List<Ksiazka> findByRokWydaniaEquals(int rokWydania);

a później tylko zrobić KsiazkaDTO

1

To co napisałeś to jest dramat jakiś. Praktycznie wszystko do zaorania.

  1. Co wg ciebie znaczy @JsonView(OnlyName.class) ?
  2. NIE wpychaj logiki do kontrolera. Kontroler woła jakąś metodę na biznesowym serwisie nie związanym z frameworkami!
  3. Nie żongluj w aplikajci obiektami Entity bo kiedyś urwie ci to głowę. Na wyjściu z repozytorium przemapuj taki obiekt na coś sensownego
  4. Zwracaj z kontrolera DTO z polami które cie interesują, czyli w twoim przypadku zrób klasę która ma te 2 pola, a nie licz na jakieś czary-mary że się automagicznie zrobi samo
  5. Nie rozumiem czemu nie wyciągasz całej ksiażki z bazy skoro już masz tam to JPA, tylko robisz jakieś cuda na kiju i kilka query po osobne kolumny. Jakbyś potrzebował 50 pól to też byś tak robił jedno po drugim?
  6. Po co w ogóle masz tam to JPA/Hibernate? W czym ci to pomaga? Bo póki co to na oko tylko ci przeszkadza.
1

Panie, weź Pan tak dla czystej nauki wywal to Spring Data i zrób to na czystym SQL używając JDBC (klasa JdbcTemplate). Przyrost skilla będzie +10. Potem jak ogarniesz absolutne podstawy, bierz się za „wspomagacze”.

1 użytkowników online, w tym zalogowanych: 0, gości: 1