24/12/26(목)
오늘 할일 : [ 일찍 자기, 푹 자기, 대박 개운하게 자기 ]이렇게 만들고 싶음. title이 하나 있고, 그 안의 여러개의 content가 있는 상황
//요청
public record TodoTitleRequest(String title) {
}
//응답
public record TodoTitleResponse(String title, Long id) {
}
@RestController
public class TodoTitleRestController {
private TodoTitleService todoTitleService;
public TodoTitleRestController(TodoTitleService todoTitleService) {
this.todoTitleService = todoTitleService;
}
@PostMapping("/todoTitles")
public TodoTitleResponse create(@RequestBody TodoTitleRequest todoTitleRequest){
return todoTitleService.create(todoTitleRequest);
}
//제목들만 보기
@GetMapping("/todoTitles")
public List<TodoTitleResponse> read(){
return todoTitleService.read();
}
@PutMapping("/todoTitles/{todoTitleId}")
public TodoTitleResponse update(@PathVariable Long todoTitleId, @RequestBody TodoTitleRequest todoTitleRequest){
return todoTitleService.update(todoTitleId, todoTitleRequest);
}
@DeleteMapping("/todoTitles/{todoTitleId}")
public void delete(@PathVariable Long todoTitleId){
todoTitleService.delete(todoTitleId);
}
}
@Entity
public class TodoTitle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
public TodoTitle() {
}
public TodoTitle(String title) {
this.title = title;
}
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
//리포지토리
public interface TodoTitleRepository extends JpaRepository<TodoTitle, Long> {
}
@Service
public class TodoTitleService {
private TodoTitleRepository todoTitleRepository;
public TodoTitleService(TodoTitleRepository todoTitleRepository) {
this.todoTitleRepository = todoTitleRepository;
}
public TodoTitleResponse create(TodoTitleRequest todoTitleRequest) {
TodoTitle todoTitle = todoTitleRepository.save(new TodoTitle(todoTitleRequest.title()));
return new TodoTitleResponse(todoTitle.getTitle(), todoTitle.getId());
}
public List<TodoTitleResponse> read() {
List<TodoTitle> titleAll = todoTitleRepository.findAll();
return titleAll.stream().map(todoTitle -> new TodoTitleResponse(todoTitle.getTitle(), todoTitle.getId())).toList();
}
@Transactional
public TodoTitleResponse update(Long todoTitleId, TodoTitleRequest todoTitleRequest) {
TodoTitle todoTitle = todoTitleRepository.findById(todoTitleId).orElseThrow();
todoTitle.setTitle(todoTitleRequest.title());
return new TodoTitleResponse(todoTitleRequest.title(),todoTitleId);
}
public void delete(Long todoTitleId) {
TodoTitle todoTitle = todoTitleRepository.findById(todoTitleId).orElseThrow();
todoTitleRepository.delete(todoTitle);
}
}
crud는 같은 내용이니까 패스!
일단 관계를 먼저 생각해보자
- title | content
하나의 title안에는 여러개의 content를 갖는다. (N)
하나의 content는 하나의 title를 갖는다. (1)
1:N관계네!
엔티티끼리 관계를 맺어줘야한다.
N인 쪽에 ManyToOne
1인 쪽에 OneToMany - 이건 근데 옵션이다. 해도되고 안해도되고
//Todo Entitiy
@Entity
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String content;
private Boolean isCompleted = false;
//관계맺기
@ManyToOne
private TodoTitle todoTitle;
public Todo(String content, TodoTitle todoTitle) {
this.content = content;
this.todoTitle = todoTitle;
}
//TodoTitle Entity
@Entity
public class TodoTitle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
//이거 그냥 옵션임 없어도됨
@OneToMany(mappedBy = "todoTitle")
private List<Todo> todo;
<나의 고민>
❓이걸 구현하기 위해서는 필요한 것들이 무엇이 있을까?
TodoRequest(요청)쪽에 title, content가 있어야한다.
그럼 요청이 들어올 때 title이 들어갈테니까 그걸 받아주는 애들(service를 수정한다.)
public record TodoRequest(
Long titleId,
String content
) {
}
request안에 titleId를 넣었으면, request를 사용하면 titleId가 사용될 것이다.
private TodoRepository todoRepository;
private final TodoTitleRepository todoTitleRepository;
public TodoService(TodoRepository todoRepository, TodoTitleRepository todoTitleRepository) {
this.todoRepository = todoRepository;
this.todoTitleRepository = todoTitleRepository;
}
public TodoResponse create(TodoRequest todoRequest) {
TodoTitle todoTitle = todoTitleRepository.findById(todoRequest.titleId()).orElseThrow(); //orElseThrow를 사용하는 이유(에러를 내주는이유): 제목이 없는 할일이 생겨버리니까
Todo save = todoRepository.save(new Todo(todoRequest.content(), todoTitle));
return new TodoResponse(save.getContent(), save.getId());
}
그럼 이제 데이터를 넣을 때 titleId까지 같이 넣어줘야 에러가 나지 않는다.
😐 느낀점
todoTitleRepository.findById(todoRequest.titleId()).orElseThrow();
이 형식을 잘 기억해두자. 내가 아는 건 titleId밖에 없으니까 이걸 활용하는 수밖에 없다.
아이디를 찾아서, 그걸 todoTitle형식으로 바꾸면 다시 save할 수 있음
이 형식을 잘 기억해서 계속해서 써먹는 방법밖에 없다!