ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스프링 부트 시작하기] 날짜 클래스(LocalDateTime) 사용하기
    스프링 부트 시작하기 2019. 9. 22. 20:48

    안녕하세요.

     

    오랜만에 새로운 포스팅을 합니다.

    이번 글부터 한동안 제 책인 [스프링 부트 시작하기]를 바탕으로 조금 잘못되었거나 보강할 내용 또는 개선할 점에 대해서 포스팅을 하려고 합니다. 기본적인 설명은 책에 나와있기 때문에 여기서는 수정하는 내용에 대해서만 설명할 예정입니다.

     

    -------------------------------------------------------------------------------------------------------------------------

     

    책을 출판하고 얼마 후, 어디선가 이런 글을 봤다.

    "아니 2019년에 나온 책이 날짜를 String으로 처리함 ㅡㅡ 아ㅋㅋㅋㅋ 진짜 핵극혐"

     

    그걸 보고 '아니 대체 어떤 ㅂㅅ이 그런 짓을 하지?ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ' 라고 생각했는데 알고보니까 그게 나였다..... 아니 대체 내가 왜 그런짓을 했던걸까.....

    그래서 이번 글에서는 그 무엇보다 먼저 날짜 처리에 대해서 빨리 써야겠다고 생각했었다. 

    다만 워낙 바쁜 일상과 더불어 게으르고 게으른 성격 덕분에(....) 이제서야 포스팅을 하게 된다.

    이번 포스팅은 책 "4.2 게시글 목록 만들기"에서 시작한다. 그리고 전체적으로 날짜 관련된 부분은 다 포함된다.

     

    1. DTO 수정하기

    BoardDto를 다음과 같이 수정한다.

     

    코드 1  BoardDto.java

    package board.board.dto;
    
    import lombok.Data;
    
    import java.time.LocalDateTime;
    import java.util.List;
    
    @Data
    public class BoardDto {
    	private int boardIdx;
    	private String title;
    	private String contents;
    	private int hitCnt;
    	private String creatorId;
    	private LocalDateTime createdDatetime;
    	private String updaterId;
    	private LocalDateTime updatedDatetime;
    	private List<BoardFileDto> fileList;
    }

     

    여기서 수정된 부분은 createdDatetime과 updatedDatetime의 형식이 String에서 LocalDateTime으로의 변경이다.

    LocalDateTime은 Java8에서 추가된 클래스로 기존의 날짜 관련된 클래스를 대신해서 여러가지 기능을 제공한다. 

    기존에 Java에서 사용하던 Date나 Calendar와 같은 날짜 관련 클래스는 사용하기 불편하기로 악명이 높았다. 어떤점이 불편했는지는 워낙 많은 포스팅에서 다루니까 패스!

     

    Java8에서는 날짜 관련 클래스가 많이 추가되었다. LocalDateTime이나 LocalDate, ZonedDateTime 등등등

    여기서는 날짜 및 시간을 같이 보여주기 때문에 LocalDateTime을 사용한다. 만약 날짜만 (년월일)만 표시한다면 LocalDate를 사용하면 된다.

     

     

    2. SQL 수정하기

    다음으로 sql을 수정할 차례다. 일단 게시글 목록을 조회하는 쿼리인 selectBoardList를 다음과 같이 변경한다.

     

    코드 2 sql-board.xml

    <select id="selectBoardList" resultType="board.board.dto.BoardDto">
    	<![CDATA[
    		SELECT
    			board_idx,
    			title,
    			hit_cnt,
    			created_datetime
    		FROM
    			t_board
    		WHERE
    			deleted_yn = 'N'
    		ORDER BY board_idx DESC
    	]]>
    </select>

     

     

    변경된 부분은 책에서는 create_datetime을 DATE_FORMAT 함수를 사용해서 원하는 모양으로 조회한거에 비해 여기서는 created_datetime을 그대로 조회한다는 것이다. 책에서 DATE_FORMAT 함수를 사용한 건 날짜를 원하는 형식으로 출력하기 위해서였는데 굳이 쿼리에서 변경할 필요도 없고, DATE_FORMAT을 사용해서 형식을 변경하면 Java의 날짜 클래스를 사용하지 못하니까 절대로 변경하면 안된다.

     

    이렇게 변경하고 게시판 목록을 조회하면 다음과 같이 보여진다.

    이렇게 정상적으로 조회되긴 하지만 몇가지 문제가 있다.

    1. 날짜 형식이 지정되어 있지 않다보니 중간에 T라는 문자가 들어가기도 하고(저 T는 무엇을 의미하는지 모르겠다...)

    2. 만약 날짜 형식을 다르게 보여주고 싶다던가 하는 요구사항이 있을 수 있다.

    따라서 화면에서 날짜 형식을 지정해서 보여줘야 한다. (일반적인 REST API에서는 화면에서 변경하지 않고 API 쪽에서 변경해서 내려줄 수도 있다. 이건 다음 포스팅에서)

     

    3. 뷰 수정하기

    다음으로 뷰를 변경할 차례다. 

    Thymeleaf는 #dates라는 오브젝트를 이용해서 날짜를 처리했다. 그렇지만 #dates는 자바 8에서 추가된 LocalDateTime이나 LocalDate를 처리할 수 없다. 이름과 같이 오직 java.utils.Date 클래스만 처리할 수 있다. 따라서 Thymeleaf 개발팀은 자바 8의 날짜 API를 처리하기 위해 #temporals이라는 새로운 오브텍트를 추가했다. #temporals 오브젝트를 이용해서 날짜를 원하는 형식으로 표시할 수 있다. 

     

    게시글 목록의 날짜를 표현하는 부분을 다음과 같이 변경한다.

     

    코드 3 restBoardList.html

    <tbody>
      <tr th:if="${#lists.size(list)} > 0" th:each="list : ${list}">
        <td th:text="${list.boardIdx}"></td>
        <td class="title"><a href="/board/" th:attrappend="href=${list.boardIdx}" th:text="${list.title}"></a></td>
        <td th:text="${list.hitCnt}"></td>
        <td th:text="${#temporals.format(list.createdDatetime, 'yyyy-MM-dd HH:mm:ss')}"></td>
      </tr> 
      <tr th:unless="${#lists.size(list)} > 0">
    	  <td colspan="4">조회된 결과가 없습니다.</td>
      </tr>
    </tbody>

     

    변경된 부분은 날짜를 보여주는 <td th:text="${#temporals.format(list.createdDatetime, 'yyyy-MM-dd HH:mm:ss')}"></td> 태그다. 책에서는 쿼리에서 이미 날짜 형식을 변경해서 보여줬기 때문에 뷰에서 특별히 날짜 형식을 변경하지 않고 그냥 보여줬지만 이번에는 #temporals 오브젝트의 format 기능을 이용해서 날짜 형식을 표현했다. 만약 책에서와 같이 [2019.09.15 21:25:58] 와 같은 형식으로 표현하고 싶다면 

    ${#temporals.format(list.createdDatetime, 'yyyy.MM.dd HH:mm:ss')}

    와 같이 표현하면 된다.

     

    이렇게 변경하고 다시 실행결과를 보면 다음과 같다.

    뷰에서 지정한 형식으로 바뀌어서 작성일이 표시된 것을 볼 수 있다. 

     

    -------------------------------------------------------------------------------------------------------------------------

     

    이번 글에서는 책에서 String을 사용한 날짜 표시를 LocalDateTime으로 변경하였습니다. 여기서는 간단히 BoardDto 클래스와 restBoardList.html 파일만 수정했지만 책에서 날짜 관련된 부분은 전부 이렇게 바꾸셔야 합니다.

     

    자바 8에 추가된 날짜 클래스들은 날짜 관련된 여러가지 기능을 제공하기 때문에 날짜 관련된 기능을 구현할 때는 꼭 Java 8의 날짜 클래스를 사용해야 합니다. (책에서는 날짜를 왜 String을 사용하도록 했었는지는 지금도 의문입니다...ㅠㅠ) 

    실제로 개발하다보면 날짜 관련된 계산을 많이 하게 됩니다. 예를 들어 날짜 더하기, 빼기, 특정한 날짜까지 몇일 남았는지, 날짜가 큰지 작은지 등등등

    LocalDateTime을 비롯한 Java 8의 날짜 클래스는 기존 자바의 Date나 Calendar 클래스의 부족함을 보완해서 사용하기 쉽고 날짜 관련된 계산을 쉽게 할 수 있도록 만들어졌습니다. 

    실제로 저도 개발하면서 날짜 관련된 계산을 많이 하는데 LocalDateTime 클래스의 여러가지 기능을 통해서 쉽게 구현할 수 있었습니다. 

    따라서 여러분들도 날짜는 꼭 자바 8의 날짜 관련 클래스를 사용하시는게 좋습니다. 

     

    다음 포스팅에는 이번 글에 이어서 REST API에서 날짜 형식을 지정해서 결과값을 보내주는 방법에 대해서 알아보겠습니다.

     

    댓글

Designed by Tistory.