Spring-Boot 查询 SELECT * FROM book (MANY to MANY rel with user) 不能正常工作
Spring-Boot Query SELECT * FROM book (MANY to MANY rel with user) doesn't work properly
我正在尝试 return 我数据库中的所有书籍,但是一旦我将值插入到名为 COLLECTION 的连接 table 中(用于解决 Many-to-Many Rel在 BOOK 和 USER 之间)我收到的输出看起来像一个循环(用 Postman 测试过)。
图书实体的实现:
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Book {
@Id
private Integer id;
private String title;
private String author;
private String description;
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
private Set<Collection> collections;
public Book(String title, String author, String description) {
this.title = title;
this.author = author;
this.description = description;
}
public Book(String title, String author Collection... collections){
this.title = title;
this.author = author;
for (Collection collection : collections){
collection.setBook(this);
}
this.collections = Stream.of(collections).collect(Collectors.toSet());
}
}
用户实体的实现:
@Getter
@Setter
@NoArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String email;
private String password;
private String username;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<Collection> collections = new HashSet<>();
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
Collection实体:
@Getter
@Setter
@NoArgsConstructor
@Entity
public class Collection implements Serializable {
@Id
@ManyToOne
@JoinColumn
private Book book;
@Id
@ManyToOne
@JoinColumn
private User user;
public Collection(User user){
this.user = user;
}
@Override
public boolean equals(Object o){
if(this == o) return true;
if(!(o instanceof Collection)) return false;
Collection that = (Collection) o;
return Objects.equals(book.getTitle(), that.book.getTitle()) &&
Objects.equals(book.getAuthor(), that.book.getAuthor()) &&
Objects.equals(user.getUsername(), that.user.getUsername());
}
@Override
public int hashCode(){
return Objects.hash(book.getTitle(), book.getAuthor(), user.getUsername());
}
}
最后是 BookRepository:
@Transactional
@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {
// this causes sql syntax error
// @Query(value = "SELECT b.id, b.title, b.author FROM book b", nativeQuery = true)
// List<Book> getAllBooks();
// this returns the loopy output from postman detailed below
List<Book> findAll();
}
我在 Postman 中收到的输出看起来像一个循环:
[{"id":1,"title":"Pride and Prejudice","author":"Jane Austen","users":[{"id":1,"email":"a@a.com","password":"a$BVXUCumzWyec9zEUeCv1r.m2pFwvAe7Cp1dLjiGfXuEEIHkhn3jHO","username":"user","books":[{"id":1,"title":"Pride and Prejudice","author":"Jane Austen", "users":[{"id":1,"email":"a@a.com","password":"a$BVXUCumzWyec9zEUeCv1r.m2pFwvAe7Cp1dLjiGfXuEEIHkhn3jHO, "username":"user","books": .......
预期的输出应该是我在数据库中的所有书籍的列表。
要设置图书和用户之间的关系,请使用@ManyToMany 映射设置直接关系。
作为参考,您可以选择以下 link-
https://www.callicoder.com/hibernate-spring-boot-jpa-many-to-many-mapping-example/
此外,您无需显式定义 findAll(),Jpa 存储库本身提供了这些通用方法。
我正在尝试 return 我数据库中的所有书籍,但是一旦我将值插入到名为 COLLECTION 的连接 table 中(用于解决 Many-to-Many Rel在 BOOK 和 USER 之间)我收到的输出看起来像一个循环(用 Postman 测试过)。
图书实体的实现:
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Book {
@Id
private Integer id;
private String title;
private String author;
private String description;
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
private Set<Collection> collections;
public Book(String title, String author, String description) {
this.title = title;
this.author = author;
this.description = description;
}
public Book(String title, String author Collection... collections){
this.title = title;
this.author = author;
for (Collection collection : collections){
collection.setBook(this);
}
this.collections = Stream.of(collections).collect(Collectors.toSet());
}
}
用户实体的实现:
@Getter
@Setter
@NoArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String email;
private String password;
private String username;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<Collection> collections = new HashSet<>();
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
Collection实体:
@Getter
@Setter
@NoArgsConstructor
@Entity
public class Collection implements Serializable {
@Id
@ManyToOne
@JoinColumn
private Book book;
@Id
@ManyToOne
@JoinColumn
private User user;
public Collection(User user){
this.user = user;
}
@Override
public boolean equals(Object o){
if(this == o) return true;
if(!(o instanceof Collection)) return false;
Collection that = (Collection) o;
return Objects.equals(book.getTitle(), that.book.getTitle()) &&
Objects.equals(book.getAuthor(), that.book.getAuthor()) &&
Objects.equals(user.getUsername(), that.user.getUsername());
}
@Override
public int hashCode(){
return Objects.hash(book.getTitle(), book.getAuthor(), user.getUsername());
}
}
最后是 BookRepository:
@Transactional
@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {
// this causes sql syntax error
// @Query(value = "SELECT b.id, b.title, b.author FROM book b", nativeQuery = true)
// List<Book> getAllBooks();
// this returns the loopy output from postman detailed below
List<Book> findAll();
}
我在 Postman 中收到的输出看起来像一个循环:
[{"id":1,"title":"Pride and Prejudice","author":"Jane Austen","users":[{"id":1,"email":"a@a.com","password":"a$BVXUCumzWyec9zEUeCv1r.m2pFwvAe7Cp1dLjiGfXuEEIHkhn3jHO","username":"user","books":[{"id":1,"title":"Pride and Prejudice","author":"Jane Austen", "users":[{"id":1,"email":"a@a.com","password":"a$BVXUCumzWyec9zEUeCv1r.m2pFwvAe7Cp1dLjiGfXuEEIHkhn3jHO, "username":"user","books": .......
预期的输出应该是我在数据库中的所有书籍的列表。
要设置图书和用户之间的关系,请使用@ManyToMany 映射设置直接关系。 作为参考,您可以选择以下 link-
https://www.callicoder.com/hibernate-spring-boot-jpa-many-to-many-mapping-example/
此外,您无需显式定义 findAll(),Jpa 存储库本身提供了这些通用方法。