Board Class에 User 정보를 넣어주자.
게시글 입장에서 사용자는 다대일 관계
사용자 입장에서는 게시글과 일대다 관계
참고 https://zetawiki.com/wiki/MySQL_%ED%85%8C%EC%9D%B4%EB%B8%94_%EC%BB%AC%EB%9F%BC_%EC%B6%94%EA%B0%80
MySQL 테이블 컬럼 추가 - 제타위키
다음 문자열 포함...
zetawiki.com
board 테이블에 user_id 컬럼을 만들고 user_id 컬럼을 user의 id 컬럼을 참조하여 외래키로 만들어준다.
MySQL [mydb]> ALTER TABLE board ADD user_id BIGINT(20);
Query OK, 0 rows affected, 1 warning (0.028 sec)
Records: 0 Duplicates: 0 Warnings: 1
MySQL [mydb]> SELECT * FROM BOARD;
+----+--------+---------+---------+
| id | title | content | user_id |
+----+--------+---------+---------+
| 1 | 제목 | 내용 | NULL |
| 2 | 헬로 | 월드 | NULL |
+----+--------+---------+---------+
2 rows in set (0.001 sec)
MySQL [mydb]> alter table board add FOREIGN KEY(user_id) REFERENCES user(id);
Query OK, 2 rows affected (0.033 sec)
Records: 2 Duplicates: 0 Warnings: 0
BoardController에 form에 postmapping을 아래와 같이 설정 해준다.
@PostMapping("/form")
public String postForm(@Valid Board board, BindingResult bindingResult) {
boardValidator.validate(board, bindingResult);
if (bindingResult.hasErrors()) {
return "board/form";
}
board.setUser(user);
boardRepository.save(board);
return "redirect:/board/result";
}
인증정보도 같이 받아준다.(spring boot get login user도 참고해준다.)
@PostMapping("/form")
public String postForm(@Valid Board board, BindingResult bindingResult, Authentication authentication) {
boardValidator.validate(board, bindingResult);
if (bindingResult.hasErrors()) {
return "board/form";
}
String username = authentication.getName();
boardRepository.save(board);
return "redirect:/board/result";
}
BoardService Class 만들어주고
package com.example.myhome.service;
import com.example.myhome.model.Board;
import com.example.myhome.repository.BoardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BoardService {
@Autowired
private BoardRepository boardRepository;
public Board save(String username, Board board) {
}
}
BoardController을 아래와 같이 설정해준다.
package com.example.myhome.controller;
import com.example.myhome.model.Board;
import com.example.myhome.repository.BoardRepository;
import com.example.myhome.service.BoardService;
import com.example.myhome.validator.BoardValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/board")
public class BoardController {
// DI => 서버 기동될 때 인스턴스가 들어온다.
@Autowired
private BoardRepository boardRepository;
@Autowired
private BoardService boardService;
@Autowired
private BoardValidator boardValidator;
@GetMapping("/list")
public String list(Model model, @PageableDefault(size = 2) Pageable pageable,
@RequestParam(required = false, defaultValue = "") String searchText) {
Page<Board> boards = boardRepository.findByTitleContainingOrContentContaining(searchText, searchText, pageable);
int startPage = Math.max(1, boards.getPageable().getPageNumber() - 4);
int endPage = Math.min(boards.getTotalPages(), boards.getPageable().getPageNumber() + 4);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("boards", boards);
return "board/list";
}
@GetMapping("/form")
public String form(Model model, @RequestParam(required = false) Long id) {
if(id == null) {
model.addAttribute("board", new Board());
} else {
Board board = boardRepository.findById(id).orElse(null);
model.addAttribute("board", board);
}
return "board/form";
}
@PostMapping("/form")
public String postForm(@Valid Board board, BindingResult bindingResult, Authentication authentication) {
boardValidator.validate(board, bindingResult);
if (bindingResult.hasErrors()) {
return "board/form";
}
String username = authentication.getName();
boardService.save(username, board);
// boardRepository.save(board);
return "redirect:/board/result";
}
}
BoardService 아래와 같이 생성
package com.example.myhome.service;
import com.example.myhome.model.Board;
import com.example.myhome.model.User;
import com.example.myhome.repository.BoardRepository;
import com.example.myhome.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BoardService {
@Autowired
private BoardRepository boardRepository;
@Autowired
private UserRepository userRepository;
public Board save(String username, Board board) {
User user = userRepository.findByUsername(username);
board.setUser(user);
return boardRepository.save(board);
}
}
UserRepository에 findByUsername 생성
package com.example.myhome.repository;
import com.example.myhome.model.Board;
import com.example.myhome.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
UserApiController도 아래와 같이 생성해준다.
package com.example.myhome.controller;
import com.example.myhome.model.User;
import com.example.myhome.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
class UserApiController {
@Autowired
private UserRepository repository;
@GetMapping("/users")
List<User> all() {
return repository.findAll();
}
@PostMapping("/users")
User newUser(@RequestBody User newUser) {
return repository.save(newUser);
}
// Single item
@GetMapping("/users/{id}")
User one(@PathVariable Long id) {
return repository.findById(id).orElse(null);
}
@PutMapping("/users/{id}")
User replaceUser(@RequestBody User newUser, @PathVariable Long id) {
return repository.findById(id)
.map(user -> {
// user.setTitle(newuser.getTitle());
// user.setContent(newuser.getContent());
return repository.save(user);
})
.orElseGet(() -> {
newUser.setId(id);
return repository.save(newUser);
});
}
@DeleteMapping("/users/{id}")
void deleteUser(@PathVariable Long id) {
repository.deleteById(id);
}
}
그리고 User Class에는 OneToMany 어노테이션을 준다. (board user 양방향 매핑을 시켜준다.)
User Class
@OneToMany(mappedBy = "user")
private List<Board> boards = new ArrayList<>();
Board Class
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
지금 계속해서 에러가 떠서 postman으로 localhost:8080/api/users로 확인을 할 수 없다. 해결하고 자야한다.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-06-03 23:26:08.179 ERROR 75658 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'webSecurityConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
아래와 같이 postman으로 나중에 테스트를 해주자.
postman 테스트를 원활하게 하기 위해서 WebSecurityConfig를 아래와 같이 설정 해준다.
// WebSecurityConfig Class
@PutMapping("/users/{id}")
User replaceUser(@RequestBody User newUser, @PathVariable Long id) {
return repository.findById(id)
.map(user -> {
// user.setTitle(newuser.getTitle());
// user.setContent(newuser.getContent());
user.setBoards(newUser.getBoards());
return repository.save(user);
})
.orElseGet(() -> {
newUser.setId(id);
return repository.save(newUser);
});
}
User Class에서 cascade를 넣어준다.
@JsonIgnore
private List<Role> roles = new ArrayList<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
private List<Board> boards = new ArrayList<>();
UserApiController Class를 아래와 같이 나타내준다.
@PutMapping("/users/{id}")
User replaceUser(@RequestBody User newUser, @PathVariable Long id) {
return repository.findById(id)
.map(user -> {
// user.setTitle(newuser.getTitle());
// user.setContent(newuser.getContent());
user.setBoards(newUser.getBoards());
for(Board board : user.getBoards()) {
board.setUser(user);
}
return repository.save(user);
})
.orElseGet(() -> {
newUser.setId(id);
return repository.save(newUser);
});
}
그리고 로그를 확인할 수 있는 방법이 있다. 여기를 참고하자.
application.properties를 Via Loggers를 참고하여 코드를 넣어준다.
spring.datasource.url=jdbc:mariadb://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
<참고 :Spring Boot으로 웹 출시까지 #10. JPA를 이용하여 @OneToMany 관계 설정하기>
https://www.youtube.com/watch?v=wM7P-6_CHFM&list=PLPtc9qD1979DG675XufGs0-gBeb2mrona&index=10
'Spring > SpringBoot' 카테고리의 다른 글
Spring Boot으로 웹 출시까지 #12. 권한에 맞는 화면 구성 및 API 호출 & 13. JPA 이용한 커스텀 쿼리 만들기 (0) | 2022.06.06 |
---|---|
Spring Boot으로 웹 출시까지 #11. JPA로 조회방법(FetchType) 설정하기 (0) | 2022.06.04 |
Spring Boot으로 웹 출시까지 #9. Spring Security를 이용한 로그인 처리 (0) | 2022.06.03 |
Spring Boot으로 웹 출시까지 #8. JPA를 이용한 페이지 처리 및 검색 (0) | 2022.06.02 |
Spring Boot으로 웹 출시까지 #7. JPA이용한 RESTful API 작성 (0) | 2022.06.02 |