<form th:action="@{/tasks}" th:object="${task}" method="post">
<label for="taskName">Task 이름:</label>
<input type="text" id="taskName" th:field="*{taskName}" placeholder="Task 이름" required/>
<label for="status">상태:</label>
<input type="text" id="status" th:field="*{status}" placeholder="상태" required/>
<label for="totoId">Toto ID:</label>
<input type="number" id="totoId" th:field="*{toto.totoNo}" placeholder="Toto ID" required/>
<button type="submit">저장</button>
</form>
Task 엔티티 생성
Task 엔티티는 작업의 이름, 상태, 생성/수정 시간을 관리하며, Toto라는 다른 엔티티와 다대일 관계로 연결된다. writeDt와 modifyDt는 자동으로 현재 날짜와 시간을 설정하며, status는 입력되지 않았을 때 기본값으로 "N"을 설정.
package com.babobird.Toto.entity;
import com.babobird.Toto.dto.TaskFormDto;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
@Entity
@Table(name="task")
@Getter
@Setter
@ToString
public class Task{
@Id
@Column(name = "task_no")
@GeneratedValue(strategy = GenerationType.AUTO)
private int taskNo; // 할 일 번호
@Column(name="task_nm", nullable = false, length = 100)
private String taskNm; // 할 일 이름
@Enumerated(EnumType.STRING)
@Column(name="task_status")
private TaskStatus status; // 진행 상태
@Column(name = "write_dt")
private LocalDateTime writeDt; // 작성일
@Column(name = "modify_dt")
private LocalDateTime modifyDt; // 수정일
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "toto_no")
private Toto toto;
// @PrePersist: 엔티티가 처음 저장될 때 실행
@PrePersist
protected void onCreate() {
if (status == null) {
status = TaskStatus.N; // status가 없을 경우 기본값 "N" 설정
}
writeDt = LocalDateTime.now();
modifyDt = LocalDateTime.now();
}
// @PreUpdate: 엔티티가 업데이트될 때 실행
@PreUpdate
protected void onUpdate() {
if (status == null) {
status = TaskStatus.N; // status가 없을 경우 기본값 "N" 설정
}
modifyDt = LocalDateTime.now();
}
//getter setter
//...
}
* 참고
@ManyToOne(fetch = FetchType.LAZY)는 JPA(Java Persistence API)에서 다대일 관계(Many-to-One)를 설정할 때 사용되는 어노테이션이다. 이 어노테이션은 엔티티 간의 관계와 지연 로딩(Lazy Loading) 방식을 지정하는 역할을 한다
컨트롤러
컨트롤러는 Task 입력 폼을 보여주고, 입력된 데이터를 저장하는 역할을 합니다. 또한 Task 조회 기능도 담당합니다.
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.babobird.Toto.entity.Task;
import com.babobird.Toto.service.TaskService;
import java.util.List;
@Controller
public class TaskController {
private final TaskService taskService;
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
// Task 입력 폼을 제공하는 GET 메서드
@GetMapping("/tasks/new")
public String showTaskForm(Model model) {
model.addAttribute("task", new Task());
return "task-form";
}
// Task 입력을 처리하는 POST 메서드
@PostMapping("/tasks")
public String saveTask(@ModelAttribute Task task) {
taskService.saveTask(task);
return "redirect:/tasks";
}
// 특정 Toto의 Task 목록을 조회하는 GET 메서드
@GetMapping("/totos/{totoNo}/tasks")
public String getTasksByTotoNo(@PathVariable int totoNo, Model model) {
List<Task> tasks = taskService.getTasksByTotoNo(totoNo);
model.addAttribute("tasks", tasks);
return "layouts/tasks";
}
}
문제와 해결 과정
1. Task 입력 기능 개발 중 발생한 문제
Task 입력 폼을 만들고, 컨트롤러에서 이 폼을 렌더링하도록 했지만 Thymeleaf 템플릿 처리 오류가 발생
오류 메시지:
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "" (template: "task/inputForm" - line 20, col 28)
원인:
이 오류는 Thymeleaf가 템플릿에서 표현식을 처리하는 중에 발생. 컨트롤러에서 모델에 task 객체를 전달하지 않아서 템플릿에서 task 객체를 찾을 수 없었기 때문이다.
문제 해결:
- 모델에 Task 객체 추가
컨트롤러에서 모델에 task 객체를 추가하지 않았기 때문에 템플릿에서 해당 객체를 찾을 수 없었다. 이를 해결하기 위해 컨트롤러에서 Task 객체를 모델에 추가하는 코드를 작성.
@GetMapping("/tasks/new")
public String showTaskForm(Model model) {
model.addAttribute("task", new Task()); // Task 객체를 모델에 추가
return "task-form";
}
2. Task 상태 기본값 설정 관련 문제
Task 입력 폼에서 status 값을 비워두고 저장했을 때, 저장된 데이터에서 status가 null로 남아있는 문제가 있었다.
해결 방법:
이 문제를 해결하기 위해, Task 엔티티에서 status 필드가 비어 있으면 기본값 "N"을 설정하도록 **@PrePersist**와 **@PreUpdate**를 사용
@Entity
public class Task {
...
@PrePersist
protected void onCreate() {
if (status == null || status.isEmpty()) {
status = "N"; // 기본값 설정
}
}
@PreUpdate
protected void onUpdate() {
if (status == null || status.isEmpty()) {
status = "N"; // 기본값 설정
}
}
}
결론
이번 포스팅에서는 Spring Boot와 Thymeleaf를 사용하여 Task 입력 및 조회 기능을 구현했다. 엔티티 관리와 날짜 처리, 기본값 설정 등을 통해 작업을 효율적으로 처리했다. 다음 작업은 수정, 삭제 작업을 진행할 예정이다.
'사이드 프로젝트 > To do list' 카테고리의 다른 글
[Spring project] Spring Boot Todo 리스트 관리: Todo 데이터 수정 및 삭제 처리 (1) | 2024.10.16 |
---|---|
[Spring project] Spring Boot Todo 리스트 관리: 삭제 기능 구현 및 Task 입력 기능 (0) | 2024.10.13 |
[Spring Project] To do 리스트 조회 (0) | 2024.10.05 |
[Spring project] 테이블 설계 (0) | 2024.08.03 |
[Spring project] 비즈니스 요구사항 정리 (0) | 2024.07.27 |