1. Todo 목록 기능 개발
등록 기능의 개발이 완료된 후 결과 화면은 목록으로 이동
목록의 경우 나중에 페이징 처리나 검색 기능이 필요하지만 시작하는 단계에서는 목록 데이터를 출력하는 수준으로 작성
1) TodoMapper의 개발
TodoMapper 인터페이스에 가장 최근에 등록된 TodoVO가 우선적으로 나올 수 있도록 selectAll()를 추가
public interface TodoMapper {
String getTime();
void insert(TodoVO todoVO);
List<TodoVO> selectAll();
}
TodoMapper.xml에서는 selectAll()의 실제 쿼리문을 작성
👾 <select> 태그의 경우 resultType을 지정하는 것에 주의
➡️ resultType은 JDBC의 ResultSet의 한 행 row을 어떤 타입의 객체로 만들것인지를 지정
<select id="selectAll" resultType="com.example.spring_ex_01_2404.domain.TodoVO">
SELECT * FROM tbl_todo ORDER BY tno DESC
</select>
마지막으로 test 폴더 내에 작성해둔 TodoMapperTests 클래스를 이용해 테스트 코드를 작성
@Test
public void testSelectAll() {
List<TodoVO> todoVOList = todoMapper.selectAll();
for (TodoVO todoVO : todoVOList) {
log.info(todoVO);
}
todoVOList.forEach(item -> log.info(item));
// for문과 foreach문 둘 중 하나 사용
}
✓ 테스트 실행 결과는 가장 나중에 추가된 데이터를 우선적으로 보여줌
2) TodoService / TodoServiceImpl의 개발
서비스 계층의 개발은 특별한 파라미터가 없는 경우 TodoMapper을 호출하는것이 전부이다. 다만, TodoMapper가 반환하는 데이터의 타입이 List<TodoVO>이기 때문에 이를 List<TodoDTO>로 변환하는 작업이 필요.
TodoService 인터페이스에 getAll() 기능을 추가
public interface TodoService {
void register(TodoDTO todoDTO);
List<TodoDTO> getAll();
}
TodoServiceImpl에서 getAll()을 작성
@Override
public List<TodoDTO> getAll() {
List<TodoVO> voList = todoMapper.selectAll(); // dao에서 데이터베이스에서 들고온 VO리스트를 리턴
List<TodoDTO> dtoList = new ArrayList<>();
for (TodoVO todoVO: voList) {
// 개별 VO를 DTO로 변환.
TodoDTO todoDTO = modelMapper.map(todoVO, TodoDTO.class);
dtoList.add(todoDTO); // DTO리스트에 저장.
}
return dtoList;
}
💡 List<TodoVO>를 List<TodoDTO>로 변화하는 작업은 java8부터 지원하는 stream을 이용해서 각 TodoVO는 map()을 통해서 TodoDTO로 바꾸고, collect()를 이용해서 List로 묶어 줌
test 코드 작성후 실행
@Test
public void testGetAll() {
List<TodoDTO> todoDTOList = todoService.getAll();
for (TodoDTO todoDTO: todoDTOList) {
log.info(todoDTO);
}
todoDTOList.forEach(item -> log.info(item));
// 둘 중 하나 사용
}
3) TodoController의 처리
TodoController의 list() 기능에서 TodoService를 처리하고 Model에 데이터를 담아서 JSP로 전달
@RequestMapping("/list")
public void list(Model model) {
log.info("todo list...");
model.addAttribute("dtoList", todoService.getAll());
}
✓ Model에는 dtoList라는 이름으로 목록 데이터를 담았기 때문에 JSP에서는 JSTL을 이용해서 목록을 출력
✓ 화면 디자인은 부트스트랩의 tables 항목 참고
/WEB-INF/view/todo/list.jsp 페이지 생성
- test.html 을 복사후 상단에 JSP, JSTL 설정 추가
- <div class="card-body"> 부분을 아래와 같이 수정
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<table class="table">
<thead>
<tr>
<th scope="col">tno</th>
<th scope="col">Title</th>
<th scope="col">Writer</th>
<th scope="col">DueDate</th>
<th scope="col">Finished</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${dtoList}">
<tr>
<th scope="row">${dto.tno}</th>
<td>${dto.title}</td>
<td>${dto.writer}</td>
<td>${dto.dueDate}</td>
<td>${dto.finished}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
2. Todo 조회 기능 개발
목록 화면에서 제목을 클릭했을때 "/todo/read?tno=xx"와 같이 TodoController를 호출하도록 개발
1) TodoMapper 조회 기능 개발
TodoMapper의 개발은 selectOne()이라는 메소드를 추가
👾 파라미터는 Long 타입으로 tno를 받도록 설계하고, TodoVO객체를 반환하도록 구성
public interface TodoMapper {
String getTime();
void insert(TodoVO todoVO);
List<TodoVO> selectAll();
TodoVO selectOne(Long tno);
}
TodoMapper.xml에 selectOne 추가
<select id="selectOne" resultType="com.example.spring_ex_01_2404.domain.TodoVO">
SELECT * FROM tbl_todo WHERE tno = #{tno}
</select>
test 코드 작성
@Test
public void testSelectOne() {
TodoVO todoVO = todoMapper.selectOne(2L);
log.info(todoVO);
}
2) TodoService / TodoServiceImpl의 개발
public interface TodoService {
void register(TodoDTO todoDTO);
List<TodoDTO> getAll();
TodoDTO getOne(Long tno);
}
@Override
public TodoDTO getOne(Long tno) {
TodoVO todoVO = todoMapper.selectOne(tno);
TodoDTO todoDTO = modelMapper.map(todoVO, TodoDTO.class);
return todoDTO;
}
3) TodoController의 개발
GET방식으로 동작하는 read() 기능을 개발
@GetMapping("/read")
public void read(Long tno, Model model) {
// 1) request로 전달 받은 tno를 서비스에 전달해서 2)TodoDTO를 반환받아서 3)View 에 전달
TodoDTO todoDTO = todoService.getOne(tno);
log.info(todoDTO);
model.addAttribute("dto", todoDTO);
}
read.jsp 파일 생성
<div class="card-body">
<div class="input-group mb-3">
<span class="input-group-text">Tno</span>
<input type="text" name="tno" class="form-control" value="${dto.tno}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Title</span>
<input type="text" name="title" class="form-control" value="${dto.title}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">DueDate</span>
<input type="date" name="dueDate" class="form-control" value="${dto.dueDate}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Writer</span>
<input type="text" name="writer" class="form-control" value="${dto.writer}" readonly>
</div>
<div class="form-check">
<label class="form-check-label">
Finished
</label>
<input type="checkbox" name="finished" class="form-check-input" ${dto.finished ? "checked" : ""} disabled>
</div>
<div class="my-4">
<div class="float-end">
<button type="submit" class="btn btn-primary">Modify</button>
<button type="reset" class="btn btn-secondary">List</button>
</div>
</div>
</div>
4) 수정 / 삭제를 위한 링크 처리
조회 화면에 수정 / 삭제를 위해서 Modify 버튼을 클릭하면 GET 방식의 수정 / 삭제 선택이 가능한 화면으로 이동
➡️ 자바 스크립트를 이용해서 이벤트 처리
read.jsp 의 card-body 클래스 아래에 코드 작성
<script>
document.querySelector('.btn-primary').addEventListener('click', function () {
self.location = '/todo/modify?tno=' + ${dto.tno};
});
document.querySelector('.btn-secondary').addEventListener('click', function () {
self.location = '/todo/list';
})
</script>
list.jsp의 링크 처리
<tbody>
<c:forEach var="dto" items="${responseDTO.dtoList}">
<tr>
<th scope="row">${dto.tno}</th>
<td><a href="/todo/read?tno=${dto.tno}" class="text-decoration-none">
${dto.title}</a></td>
<td>${dto.writer}</td>
<td>${dto.dueDate}</td>
<td>${dto.finished}</td>
</tr>
</c:forEach>
</tbody>
[ 내용 참고 : IT 학원 강의 ]
'Spring & Spring Boot' 카테고리의 다른 글
[Spring] 페이징 처리를 위한 TodoMapper (0) | 2024.04.28 |
---|---|
[Spring] Todo의 삭제 | 수정 기능 개발 (1) | 2024.04.28 |
[Spring] Todo 기능 개발 | 한글 처리 필터 설정 | 유효성 검사 @Valid (0) | 2024.04.28 |
[Spring] 프로젝트 구현 준비 | 부트스트랩 적용 | DB 처리 (0) | 2024.04.27 |
[Spring] 스프링 Web MVC (0) | 2024.04.24 |