书课:
@Table(name = "Books")
@Entity
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Book {
@Id
@SequenceGenerator(
name = "book_sequence",
sequenceName = "book_sequence",
allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "book_sequence"
)
private Long bookId;
private String title;
private LocalDate releaseDate;
private String genresStr;
@Column(columnDefinition = "text")
private String content;
@ManyToMany(mappedBy="books", fetch=FetchType.LAZY, cascade = CascadeType.ALL)
private Set<Users> authors;
public Book(String title, LocalDate releaseDate, String content, String genresStr){
this.genresStr = genresStr;
this.title= title;
this.releaseDate = releaseDate;
this.content = content;
}
public Book(String title, LocalDate releaseDate, String content, String genresStr, Set<Users> authors){
this.genresStr = genresStr;
this.title= title;
this.releaseDate = releaseDate;
this.content = content;
this.authors = authors;
}
public void addAuthors(Set<Users> authors){
System.out.println("addAuthorsCalled");
for(Users author : authors)
try{
this.authors.add(author);
author.addBooks(Set.of(this));
author.setRole(Roles.AUTHOR);
} catch(Exception e){
System.out.println("Wrong type of object for a List of Users");
}
}
public void removeAuthors(Set<Users> authors){
if(authors.size() == 1){
System.out.println("Can't delete all authors for certain book");
return;
}
for(Users author : authors)
for(Users user : this.authors){
if (user.equals(author)) {
this.authors.remove(user);
}
else{
System.out.println("User: "+author.getFullName()+ " is already not in set.");
}
}
}
}
书控制器:
@RestController
@RequestMapping(path = "api/books")
public class BookController {
private final BookService bookService;
private UserService userService;
public BookController(@Autowired BookService bookService, UserService userService){
this.bookService = bookService;
this.userService = userService;
}
@GetMapping
public List<Book> getBooks(){
return bookService.getBooks();
}
@PostMapping
public void addBook(@RequestBody Book book){
if(!book.getAuthors().isEmpty()){
for(Users author : book.getAuthors()){
author.setRole(Roles.AUTHOR);
userService.saveUser(author);
}
}
bookService.saveBook(book);
}
@DeleteMapping(path="{bookId}")
public void deleteBook(@PathVariable ("bookId") Long bookId){
bookService.deleteBook(bookId);
}
@PutMapping(path="{bookId}")
public void updateBook(
@PathVariable("bookId") Long bookId,
@RequestParam(required = false) String title,
@RequestParam(required = false) LocalDate releaseDate,
@RequestParam(required = false) String content,
@RequestParam(required = false) Set<Long> userIds
){
Set<Users> usersToAdd = null;
if(userIds!=null){
usersToAdd = userService.getUsersById(userIds);
}
bookService.updateBook(bookId, title, releaseDate, content, usersToAdd);
}
@PutMapping(path = "/{bookId}/delAuthor")
public void putMethodName(
@PathVariable Long bookId,
@RequestParam(required = true) Set<Long> userIds
){
Set<Users> usersToRemove = userService.getUsersById(userIds);
bookService.removeAuthors(bookId, usersToRemove);
}
}
用户控制器:
@RestController
@RequestMapping(path = "api/users")
public class UserController {
private final UserService userService;
public UserController(@Autowired UserService userService){
this.userService = userService;
}
@GetMapping
public List<Users> getAllUsers() {
return userService.getUsers();
}
@PostMapping
public void addNewUser(@RequestBody Users user) {
userService.saveUser(user);
}
@DeleteMapping(path="{userId}")
void deleteUser(@PathVariable ("userId") Long userId){
userService.deleteUser(userId);
}
@PutMapping(path="{userId}")
void updateUser(@PathVariable ("userId") Long userId,
@RequestParam(required = false) String fullName,
@RequestParam(required = false) String password,
@RequestParam(required = false) LocalDate dateOfBirth,
@RequestParam(required = false) String email,
@RequestParam(required = false) Set<Long> bookIds
){
userService.updateUser(userId, password, dateOfBirth, fullName, email, bookIds);
}
}
用户服务
@Service
public class UserService {
private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
private final UserRepository userRepository;
private BookRepository bookRepository;
public UserService(@Autowired UserRepository userRepository, BookRepository bookRepository){
this.userRepository = userRepository;
this.bookRepository = bookRepository;
}
public Users getUser(Long id){
return this.userRepository.getReferenceById(id);
}
public List<Users> getUsers(){
return this.userRepository.findAll();
}
public Set<Users> getUsersById(Set<Long> userIds){
Set<Users> users = new HashSet<>();
for(Long userId : userIds)
if(userId != null){
users.add(this.getUser(userId));
}
return users;
}
public void saveUser(Users user){
Optional<Users> userEmailOptional = userRepository.findUserByEmail(user.getEmail());
if(userEmailOptional.isPresent()){
throw new IllegalStateException("This email already exists in database");
}
if(user.getRole() == Roles.AUTHOR){
Optional<Users> authorByFullName = userRepository.findUserByFullName(user.getFullName());
if(authorByFullName.isPresent()){
throw new IllegalStateException("Authors cannot have the same name");
}
}
if(user.getBooks() != null && !user.getBooks().isEmpty())
user.setRole(Roles.AUTHOR);
user.setPassword(encoder.encode(user.getPassword()));
if(user.getBooks() != null && !user.getBooks().isEmpty())
for(Book book : user.getBooks())
bookRepository.save(book);
userRepository.save(user);
}
public void deleteUser(Long userId){
boolean exists = userRepository.existsById(userId);
if(!exists){
throw new IllegalStateException("No user with Id: " + userId+ " in database");
}
userRepository.deleteById(userId);
}
@Transactional
public void updateUser(Long userId,
String password,
LocalDate dateOfBirth,
String fullName,
String email,
Set<Long> bookIds){
Users user = userRepository.findById(userId).orElseThrow(() ->
new IllegalStateException("No user with id: "+userId+" in database"));
if(password != null && password.length() > 0){
user.setPassword(password);
}
if(dateOfBirth!=null){
user.setDateOfBirth(dateOfBirth);
}
if(fullName!=null && fullName.length() > 0){
user.setFullName(fullName);
}
if(email!=null && email.length() > 0){
Optional<Users> userOptional = userRepository.findUserByEmail(email);
if(userOptional.isPresent()){
throw new IllegalStateException("Email "+email+" already exists in database");
}
user.setEmail(email);
}
if(bookIds != null){
Set<Book> booksToAdd = new HashSet<Book>();
for(Long bookId : bookIds){
booksToAdd.add(bookRepository.getReferenceById(bookId));
}
user.addBooks(booksToAdd);
}
}
}
书服务:
@Service
public class BookService {
private final BookRepository bookRepository;
public BookService(@Autowired BookRepository bookRepository){
this.bookRepository = bookRepository;
}
public List<Book> getBooks(){
return bookRepository.findAll();
//List.of(new Book("kostas", LocalDate.of(2000, Month.APRIL, 12)));
}
public void saveBook(Book book){
bookRepository.save(book);
}
public void deleteBook(Long bookId){
boolean exists = bookRepository.existsById(bookId);
if(!exists){
throw new IllegalStateException("Book with id: " + bookId + " does not exist");
}
bookRepository.deleteById(bookId);
}
@Transactional
public void removeAuthors(Long bookId, Set<Users> authors){
Book book = bookRepository.findById(bookId).
orElseThrow(() -> new IllegalStateException("No books with the id requested"));
if(!authors.isEmpty())
book.removeAuthors(authors);
}
@Transactional
public void updateBook(Long bookId, String title, LocalDate releasDate, String content, Set<Users> authors){
Book book = bookRepository.findById(bookId).
orElseThrow(() -> new IllegalStateException("No books with the id requested"));
if(title != null && title.length() > 0){
book.setTitle(title);
}
if(releasDate != null){
book.setReleaseDate(releasDate);
}
if(content != null && content.length() > 0){
book.setContent(content);
}
if(authors != null)
book.addAuthors(authors);
}
}
形是一个简单的枚举:
public enum Roles {
AUTHOR, ADMIN, GUEST
}
postman请求的示例:post:localhost:8080/api/用户
//用书插入用户 //正常工作body:
{
"password":"itsDanBrown",
"dateOfBirth":"1964-07-22",
"fullName":"Dan Brown",
"email":"[email protected]",
"books":[
{
"title":"The Da Vinci Code",
"releaseDate":"2003-03-18",
"content":"",
"genres":["Mystery", "detective fiction", "conspiracy fiction", "thriller"]
},
{
"title":"Angels & Demons",
"releaseDate":"2000-05-30",
"content":"",
"genres":["Mystery", "thriller"]
}
]
}
post:localhost:8080/api/用户
//与用户插入书 //在用户表和书籍表中插入值,但在用户_Books表{
"title":"The Da Vinci Code",
"releaseDate":"2003-03-18",
"content":"",
"genres":["Mystery", "detective fiction", "conspiracy fiction", "thriller"],
"authors":[
{
"password":"password",
"dateOfBirth":"2000-02-02",
"fullName":"Dan Brown",
"email": "[email protected]"
}
]
}
提前感谢! (Java版本18,Spring Boot 3.4.2)
在您的示例中,用户是关系的自然方面。 当您致电 /用户端点时: 用户服务单独保存(从请求)。 然后,它保存了用户 - 与所有书籍相关联。 此序列允许Hibernate在users_books Join表中创建链接。 aissue with /books端点
USERS_BOOKS加入表中创建一个条目。
如何修复if (!book.getAuthors().isEmpty()) {
for (Users author : book.getAuthors()) {
author.setRole(Roles.AUTHOR);
author.addBooks(Set.of(book)); // Establish the bidirectional link
userService.saveUser(author);
}
}
bookService.saveBook(book);