본문 바로가기
Java/└ Mybatis

Mybatis) 여러 건 조회하기 (JSTL 이용하여 문자열을 Date형식으로 파싱하기)

by 박채니 2022. 8. 8.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


여러 건 조회하기 DTO

 

url-command.properties

/student/selectList.do = com.ce.app.student.controller.SelectListController

 

Controller

SelectListController

@Log4j
@RequiredArgsConstructor
public class SelectListController extends AbstractController {
	private final StudentService studentService;
	
	@Override
	public String doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Student> list = studentService.selectStudentList();
		log.debug("list = " + list);
		request.setAttribute("list", list);
		return "student/selectList";
	}
}

@콘솔출력값
2022-08-08 14:48:35 DEBUG SelectListController:25 - list = [Student(no=1, name=홍길동, tel=01012341234, createdAt=2022-08-04T21:10:53, updatedAt=null, deletedAt=null), Student(no=2, name=신사임둥, tel=01011112222, createdAt=2022-08-04T21:11:16, updatedAt=2022-08-08T12:27:22, deletedAt=null), Student(no=3, name=세종대왕, tel=01022223333, createdAt=2022-08-04T21:11:17, updatedAt=null, deletedAt=null), Student(no=21, name=유재석, tel=01011112222, createdAt=2022-08-05T11:48:21, updatedAt=null, deletedAt=null), Student(no=22, name=박채니, tel=01099998888, createdAt=2022-08-05T11:52:04, updatedAt=null, deletedAt=null), Student(no=41, name=손석구, tel=01055556666, createdAt=2022-08-05T13:43:58, updatedAt=null, deletedAt=null), Student(no=45, name=루피, tel=01012334123, createdAt=2022-08-05T13:51:05, updatedAt=null, deletedAt=null), Student(no=46, name=신사, tel=01046546564, createdAt=2022-08-05T13:51:14, updatedAt=null, deletedAt=null)]

 

Service

StudentServiceImpl

(interface 생략)

@Override
public List<Student> selectStudentList() {
    try(SqlSession sqlSession = getSqlSession()) {
        return studentDao.selectStudentList(sqlSession);			
    }
}

 

Dao

StudentDaoImpl

(interface 생략)

@Override
public List<Student> selectStudentList(SqlSession sqlSession) {
    return sqlSession.selectList("student.selectStudentList");
}

 

student-mapper.xml

<!-- resultType/resultMap은 레코드 하나에 대응하는 타입을 작성! -->
<!-- <select id="selectStudentList" resultType="student"> -->
<select id="selectStudentList" resultMap="studentDtoMap">
    select * from student where deleted_at is null order by no
</select>

<resultMap type="student" id="studentDtoMap"> <!-- 반환타입 : student -->
    <!-- 예측 가능한 범주일 때는 생략 가능! -->
    <id column="no" property="no"/> <!-- <id> : PK컬럼! -->
    <result column="name" property="name"/>
    <result column="tel" property="tel"/>
    <result column="created_at" property="createdAt"/> <!-- column은 대소문자 구분 X, property는 대소문자 구분 O -->
    <result column="updated_at" property="updatedAt"/>
    <result column="deleted_at" property="createdAt"/>
</resultMap>

한 레코드에 대응하는 타입을 작성해야 하기 때문에 resultType/resultMap에 'list'라고 사용하면 오류가 발생합니다.

한 레코드가 리턴하는 타입은 student 타입이므로 resultType을 student로 지정하거나 student 타입을 반환하는 resultMap을 작성해줍니다.

 

selectList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mybatis실습 - selectList</title>
<style>
div#student-container{text-align:center;}
table.tbl-student{margin:0 auto;border:1px solid; border-collapse:collapse;}
table.tbl-student th,table.tbl-student td{
	border:1px solid;
	padding:5px;
}
</style>
</head>
<body>
<div id="student-container">
	<h2>selectList</h2>
	<p>SqlSession의 selectList메소드를 호출해서 List&lt;Student>를 리턴받음.</p>
	<table class="tbl-student">
		<thead>
			<tr>
				<th>학번</th>
				<th>이름</th>
				<th>전화번호</th>
				<th>등록일</th>
				<th>수정일</th>
			</tr>
		</thead>
		<tbody>
			<c:forEach items="${list}" var="student">
				<tr>
					<td>${student.no}</td>
					<td>${student.name}</td>
					<td>${student.tel}</td>
					<td>
						<fmt:parseDate value="${student.createdAt}" pattern="yyyy-MM-dd'T'HH:mm:ss" var="createdAt" />
						<fmt:formatDate value="${createdAt}" pattern="yy/MM/dd HH:mm"/>
					</td>
					<td>
						<fmt:parseDate value="${student.updatedAt}" pattern="yyyy-MM-dd'T'HH:mm:ss" var="updatedAt"/>
						<fmt:formatDate value="${updatedAt}" pattern="yy/MM/dd HH:mm"/>
					</td>
				</tr>
			</c:forEach>
		</tbody>
	</table>
</div>
</body>
</html>

현재 createdAt, updatedAt은 LocalDateTime 타입이기 때문에 바로 fmt:formatDate를 사용할 수 없습니다.

(fmt:formatDate → java.util.Date가 value값으로 들어오길 기대!)

따라서 fmt:parseDate를 이용하여 문자열을 Date형식으로 파싱해준 후 fmt:formatDate의 value값으로 사용해주었습니다.

 


여러 건 조회하기 Map

 

Controller

SelectListController

@Log4j
@RequiredArgsConstructor
public class SelectListController extends AbstractController {
	private final StudentService studentService;
	
	@Override
	public String doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Student> list = studentService.selectStudentList();
		log.debug("list = " + list);
		request.setAttribute("list", list);
		
		// Map
		List<Map<String, Object>> mapList = studentService.selectStudentMapList();
		log.debug("mapList = " + mapList);
		request.setAttribute("mapList", mapList);
		
		return "student/selectList";
	}
}

@콘솔출력값 (Map)
2022-08-09 12:20:33 DEBUG SelectListController:31 - mapList = [{no=1, createdAt=2022-08-04 21:10:53.0, name=홍길동, tel=01012341234}, {no=2, createdAt=2022-08-04 21:11:16.0, name=신사임둥, tel=01011112222, updatedAt=2022-08-08 12:27:22.0}, {no=3, createdAt=2022-08-04 21:11:17.0, name=세종대왕, tel=01022223333}, {no=21, createdAt=2022-08-05 11:48:21.0, name=유재석, tel=01011112222}, {no=22, createdAt=2022-08-05 11:52:04.0, name=박채니, tel=01099998888}, {no=41, createdAt=2022-08-05 13:43:58.0, name=손석구, tel=01055556666}, {no=45, createdAt=2022-08-05 13:51:05.0, name=루피, tel=01012334123}, {no=46, createdAt=2022-08-05 13:51:14.0, name=신사, tel=01046546564}]

 

Service

StudentServiceImpl

(interface 생략)

@Override
public List<Map<String, Object>> selectStudentMapList() {
    try(SqlSession sqlSession = getSqlSession()) {
        return studentDao.selectStudentMapList(sqlSession);			
    }
}

 

Dao

StudentDaoImpl

(interface 생략)

@Override
public List<Map<String, Object>> selectStudentMapList(SqlSession sqlSession) {
    return sqlSession.selectList("student.selectStudentMapList");
}

 

student-mapper.xml

<select id="selectStudentMapList" resultMap="studentMap">
    select * from student where deleted_at is null order by no
</select>

<resultMap type="map" id="studentMap">
    <id column="no" property="no"/>
    <result column="name" property="name"/>
    <result column="tel" property="tel"/>
    <result column="created_at" property="createdAt"/>
    <result column="updated_at" property="updatedAt"/>
    <result column="deleted_at" property="deletedAt"/>
</resultMap>

 

selectList.jsp

<p>SqlSession의 selectList메소드를 호출해서 List&lt;Map&lt;String, Object>>를 리턴받음.</p>
<table class="tbl-student">
    <thead>
        <tr>
            <th>학번</th>
            <th>이름</th>
            <th>전화번호</th>
            <th>등록일</th>
            <th>수정일</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach items="${mapList}" var="student">
            <tr>
                <td>${student.no}</td>
                <td>${student.name}</td>
                <td>${student.tel}</td>
                <td>
                    <fmt:formatDate value="${student.createdAt}" pattern="yy/MM/dd HH:mm"/>
                </td>
                <td>
                    <fmt:formatDate value="${student.updatedAt}" pattern="yy/MM/dd HH:mm"/>
                </td>
            </tr>
        </c:forEach>
    </tbody>
</table>

Map은 자동으로 날짜 타입을 가져와 java.util.Date로 옮겨받기 때문에 <fmt:formatDate>만 사용하여 포맷팅 가능합니다.