嘿,我想创建一个扩展JpaRepository的存储库并获取结果而无需编写实际查询,在我的示例中,我有2个表Book和Author,它们之间存在多对多关系,假设我想按特定的author_id来获取图书清单,因为在我图书实体,我没有任何名为author_id的字段,因此我将如何使用JPARepository来获取结果而无需编写实际查询。我正在做这样的事情:我创建了一个BookDTO,其中包含Book和Author的对象,并且我创建了bookDTORepository来扩展JpaRepository并正在调用List<Book> findByAuthor_Id(Integer id);,但是它的抛出错误为:Not an managed type: class golive.data.bookdto我的书类是
List<Book> findByAuthor_Id(Integer id);
Not an managed type: class golive.data.bookdto
package golive.data; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Transient; import com.fasterxml.jackson.annotation.JsonIgnore; import com.sun.istack.internal.NotNull; @Entity @Table(name="book") public class Book implements java.io.Serializable{ @Id @GeneratedValue private Integer id; @NotNull @Column(name="name") private String name; @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY) @JoinTable(name = "writes", joinColumns = { @JoinColumn(name = "book_id") }, inverseJoinColumns = { @JoinColumn(name = "author_id") }) private Set<Author> authors = new HashSet<Author>(); public Set<Author> getAuthors() { return authors; } public Integer getId() { return id; } public String getName() { return name; } public void setAuthors(Set<Author> authors) { this.authors = authors; } public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } }
我的作家班是
package golive.data; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import com.fasterxml.jackson.annotation.JsonIgnore; import com.sun.istack.internal.NotNull; @Entity @Table(name="author") public class Author implements java.io.Serializable{ @Id @GeneratedValue @Column(name="id") private Integer Id; @NotNull @Column(name="name") private String name; public Integer getId() { return Id; } public String getName() { return name; } public void setId(Integer id) { Id = id; } public void setName(String name) { this.name = name; } }
我预定的课程是
package golive.data; public class bookdto { private Book book; private Author author; public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } }
我的bookDTORepository是:
package golive.data; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface bookDTORepository extends JpaRepository<bookdto, Book> { List<Book> findByAuthor_Id(Integer id); }
我添加了书控制器方法:
@RequestMapping(value = "/listbyauthor", method = RequestMethod.POST, produces = "application/json") public ResponseEntity<List<Book>> getBookByAuthorId(@RequestBody Author author,HttpServletResponse response) { try { Author temp = new Author(); temp.setId(author.getId()); temp.setName(author.getName()); return new ResponseEntity<>(bookRepository.findByAuthor(temp), HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); } return new ResponseEntity<>(HttpStatus.NO_CONTENT); }
您要查找特定作者的所有书籍,因此,在给定作者的情况下,检索其作者集中包含指定作者的所有书籍。
相关的JPQL运算符为:
http://www.objectdb.com/java/jpa/query/jpql/collection#NOT_MEMBER_OF_
[NOT] MEMBER [OF] [NOT] MEMBER OF运算符检查指定的持久性收集字段中是否包含指定的元素。 例如: 如果语言包含“英语”,则c.languages的“英语”成员为TRUE,否则为FALSE。如果语言不包含“英语”,则“英语”不属于c.languages。
[NOT] MEMBER [OF] [NOT] MEMBER OF运算符检查指定的持久性收集字段中是否包含指定的元素。
例如:
如果语言包含“英语”,则c.languages的“英语”成员为TRUE,否则为FALSE。如果语言不包含“英语”,则“英语”不属于c.languages。
您可能知道(也可能不知道),您正在使用Spring Data,它可以根据方法名称为您派生一些查询。但是,文档未提及对[NOT] MEMBER [OF]运算符的支持:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query- methods.query-creation
因此,您需要向存储库中添加一个自定义查询方法,该方法将类似于:
public interface BookRepository extends JpaRepository<Book, Integer> { @Query("select b from Book b where ?1 MEMBER OF b.authors") List<Book> findByAuthor(Author author); }
而 作为参数传递的Author是从数据库 (通过您的AuthorRepository) 检索的持久实例 。