簡體   English   中英

如何在 spring 引導存儲庫中查詢多對多關系

[英]How to query a many to many relationship in spring boot repository

我試圖讓 api 返回一個注釋列表,與標簽的多對多關系相關聯,給定一個 label id。 Spring 引導自動創建了一個名為 notes_tables 的橋接表,其中包含 notes_id 字段和 labels_id 字段。 Spring Boot 還創建了一個 notes 表和一個 labels 表。 我嘗試了以下操作:

@Query(value="select * from notes join notes_labels on note.id=notes_id join labels on labels_id=labels.id where labels_id=:lid", nativeQuery=true)
        public List<Note> findNotesForLabel(@Param("lid") int labelId);

我只需要讓它工作,但我特別好奇是否可以讓它與 jpa 方法查詢一起工作。 只要有效,任何查詢都可以。

編輯:實體注.java

package com.example.maapi.models;

import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "notes")
public class Note {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String note;
    private String title;
    private String status = "private";

    @ManyToOne
    @JsonIgnore
    private User user;

    @ManyToOne
    @JsonIgnore
    private Folder folder;

   @ManyToMany
   @JsonIgnore

   private List<Label> labels;

    public int getId() {
        return id;
    }

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

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Folder getFolder() {
        return folder;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setFolder(Folder folder) {
        this.folder = folder;
    }

   public List<Label> getLabels() {
       return labels;
   }

   public void setLabels(List<Label> labels) {
       this.labels = labels;
   }


    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Note)) {
            return false;
        }
        Note note = (Note) o;
        return id == note.id && Objects.equals(note, note.note) && 
 Objects.equals(title, note.title) && Objects.equals(status, 
 note.status) && Objects.equals(user, note.user) && 
 Objects.equals(folder, note.folder) && Objects.equals(labels, 
 note.labels);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, note, title, status, user, folder, 
 labels);
    }

}

Label.java

        package com.example.maapi.models;

        import com.fasterxml.jackson.annotation.JsonIgnore;

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

        @Entity
        @Table(name = "labels")
        public class Label {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        private String title;
        private String status = "private";

        @ManyToOne
        @JsonIgnore
        private User user;

        @ManyToOne
        @JsonIgnore
        private Folder folder;

        @ManyToMany(mappedBy = "labels")
        @JsonIgnore
        private List<Note> notes;

        public int getId() {
            return id;
        }

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

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public Folder getFolder() {
            return folder;
        }

        public void setFolder(Folder folder) {
            this.folder = folder;
        }

        public List<Note> getNotes() {
           return notes;
        }

       public void setNotes(List<Note> notes) {
           this.notes = notes;
       }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }


        @Override
        public boolean equals(Object o) {
            if (o == this)
                return true;
            if (!(o instanceof Label)) {
                return false;
            }
            Label label = (Label) o;
            return id == label.id && Objects.equals(title, label.title) && 
        Objects.equals(status, label.status) && Objects.equals(user, 
         label.user) && Objects.equals(folder, label.folder) && 
         Objects.equals(notes, label.notes);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, title, status, user, folder, notes);
        }

        }

服務:NoteService.java

package com.example.maapi.services;

import com.example.maapi.models.Folder;
import com.example.maapi.models.Note;
import com.example.maapi.models.User;
import com.example.maapi.repositories.FolderRepo;
import com.example.maapi.repositories.NoteRepo;
import com.example.maapi.repositories.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class NoteService {
    @Autowired
    NoteRepo noteRepo;
    @Autowired
    UserRepo userRepo;
    @Autowired
    FolderRepo folderRepo;

    public List<Note> findAllNotes(){
        return noteRepo.findAllNotes();
    }

    public Note findNoteById(int noteId){
        return noteRepo.findNoteById(noteId);
    }

    public List<Note> findNotesByUser(int userId){
        return noteRepo.findNotesByUser(userId);
    }

    public Note createNoteForUser(int userId, Note note){
        User user = userRepo.findUserById(userId);
        note.setUser(user);
        return noteRepo.save(note);
    }

    public List<Note> findNotesByFolder(int folderId){
        return noteRepo.findNotesByFolder(folderId);
    }

    public Note createNoteForFolder(int folderId, Note note){
        Folder folder = folderRepo.findFolderById(folderId);
        note.setFolder(folder);
        note.setUser(folder.getUser());
        return noteRepo.save(note);
    }

    public int updateNote(int noteId, Note updatedNote){
        Note note = noteRepo.findNoteById(noteId);
        updatedNote.setUser(note.getUser());
        updatedNote.setFolder(note.getFolder());
        noteRepo.save(updatedNote);
        if(updatedNote.equals(note)){
            return 1;
        } else {
            return 0;
        }
    }

    public int deleteNote(int noteId){
        noteRepo.deleteById(noteId);
        if(noteRepo.findNoteById(noteId) == null) {
            return 1;
        } else {
            return 0;
        }
    }

    // SEARCH IMPLEMENTATION

    public List<Note> searchForNote(String note){
        return noteRepo.searchForNote(note);
    }

}

標簽服務.java

試試這個!

SELECT * FROM notes n INNER JOIN notes_labels nl ON nl.notes_id = n.note_id WHERE nl.labels_id = ?1

編輯:

@Entity
@Table(name = "notes")
@NamedNativeQuery(name = "Note.getNoteByLabel", resultSetMapping = "getNote",
query = "SELECT n.id,n.note,n.title,n.status FROM notes n INNER JOIN notes_labels nl ON nl.notes_id = n.note_id WHERE nl.labels_id = ?1")
@SqlResultSetMapping(name = "getNote", classes = @ConstructorResult(targetClass = Note.class, 
columns = {@ColumnResult(name = "id", type = Integer.class),@ColumnResult(name = "note", type = String.class)
@ColumnResult(name = "title", type = String.class),@ColumnResult(name = "status", type = String.class)}))
public class Note {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String note;
    private String title;
    private String status = "private";

注意Repo.java

@Query(nativeQuery = true)
List<Note> getNoteByLabel(int labelId);

構建一個適當的構造函數並嘗試這個。

所以這是我能夠弄清楚的彈簧戰利品方法。 CrudRepository 有 findById(Integer id),它返回一個可選的 object。 您所要做的就是 optional.get() 返回封裝的 object ,然后您可以使用 getter 返回所需的字段(在我的情況下為 List notes)。

// CrudRepo interface provides the findById method which returns an Optional<Label>
    // object that may or may not exist. Optional.get() returns the encapsulated object.
    public List<Note> findNotesByLabelId(int labelId) {
      Optional<Label> label = labelRepo.findById(labelId);
        return label.get().getNotes();    
    }

您必須將其視為簡單的 POO。 例如,您可以使用:

@Query("FROM Note n WHERE (SELECT l FROM Label l WHERE l.id = :lid) MEMBER OF labels")
public List<Note> findNotesByLabel(@Param("lid") int id);

這基本上意味着,

獲取給定 id 的 label 是標簽屬性的一部分的所有注釋

我還不完全了解每個實現,當然文檔會提供更好的方法,但我只是想出了這個問題,它成功了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM