-
JPA를 이용해 최근 게시물 불러오기졸업과제/BackEnd 2023. 3. 14. 13:19
홈화면에 들어가면 최근 작성된 게시물이 보이도록 구현 도전!
분명히 JPA에서 제공하는 쿼리가 있을거라고 생각하고 일단 도전해 본다. 만약 없으면 비상상황
Repository
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.limit-query-result
Spring Data JPA - Reference Documentation
Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del
docs.spring.io
JPA에서 limit쿼리를 제공한다고 했다. 딱 나에게 필요한 기능이였다. limit 쿼리란 페이징과 유사하게
쿼리의 검색결과를 제한해서 보여주는것이다.
사용자들이 게시물을 작성할 때마다 게시물에 세팅되는 publish_date값을 가지고 가장 최신의 게시물을 조회해서 가져올 예정이다.
order by를 이용해 publish_date속성을 대상으로 내림차순 정렬해 5개의 게시물만 가져와 출력해 줄 것이다.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.limit-query-resultSpring Data JPA - Reference Documentation
Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del
docs.spring.io
public interface PostRepository extends JpaRepository<Post,Long> { List<Post> findTop5ByOrderByPublishDateDesc(); }
JPA에서 공식문서를 참고해 JPA Repository메서드를 작성해 보았다.
JPA에서 findTop5가 MySQL에서 limit 5와 일치하는 것이다.
속성 값을 정의할 때는 DB에 있는 속성이름을 기준으로 하는 게 아니라 Entity 안에 필드명을 기준으로 해준다.
나의 post Entity안에 게시물 생성 시간을 담는 필드값 이름이 publishDate로 설정돼있기 때문에
JPA기준에 따라 필드명 앞글자를 대문자로 바꿔주어 PublishDate로 설정해 준다.
Service
@Service public class PostService { @Transactional public List<RecentlyPostDto>RecentlyPost() { logger.info("[RecentlyPost] 최근 게시물 조회 로직 Service 동작."); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String DtoDate = new String(); List<RecentlyPostDto>recentlyPostDto = new ArrayList<>(); List<Post> postList = postRepository.findTop5ByOrderByPublishDateDesc(); for (Post post : postList) { DtoDate = simpleDateFormat.format(post.getPublishDate()); RecentlyPostDto build = RecentlyPostDto .builder() .postId(post.getPostId()) .title(post.getTitle()) .date(DtoDate) .build(); recentlyPostDto.add(build); } return recentlyPostDto; } }
최신게시물을 Repository에서 조회해서 받아온 뒤 최신게시물에 보이기만 하면 되는 간략한 정보들을 담아낼 Dto로
데이터를 넘긴 뒤 Controller로 전달하는 Service로직이다.
DB에 저장되어 있는 날짜를 그대로 웹페이지에 출력해 주면 날짜가 나타나는 형식이 2023-03-13 14:26:21과 같이
초단위까지 나타나 있기 때문에 사용자의 가독성이 떨어진다.
따라서 날짜의 형식을 SimpleDateFormat객체를 이용해 날짜가 나타나는 형식을 정해줬다.
SimpleDateFormat에 날짜가 나타나길 원하는 양식을 설정해 주고 이용해 Date타입의 값을 format을 해준 뒤 String으로 받아낸다.
DB에서 조회된 5개의 최신게시물들을 이용해 Dto에 필요한 값들(제목, 게시물 pk, 포맷이 변경된 날짜)을 세팅해 주고
세팅된 Dto를 Controller에 전달해 준다.
만약 Dto에 어노테이션으로 Data나 Getter, Setter가 없으면 여기서는 괜찮은데 html에서 값을 받을 때 에러가 생길 수 있으니
세팅하는 거 잊지 마셔요 (나한테 하는 말)
Controller
@Controller public class HomeController { private final PostService postService; @Autowired public HomeController(PostService postService) { this.postService = postService; } @GetMapping(value = "/") public String Home(Model model) { PostSearchDto postSearchDto = new PostSearchDto(); List<RecentlyPostDto> recentlyPost = postService.RecentlyPost(); model.addAttribute("recentlyPost",recentlyPost); model.addAttribute("dto",postSearchDto); model.addAttribute("category",AreaEnum.values()); return "home"; } }
Controller는 Service에서 최근게시물들을 조회한뒤 dto를 전달하면 dto를 model을 이용해 html에 전달하면 된다.
객체 배달원 느낌.
html
<table> <tr> <th>내용</th><th>날짜</th> </tr> <tr th:each="post : ${recentlyPost}"> <td><a th:text="${post.title}" th:href="@{/post/detailPost/{postId}(postId = ${post.postId})}">룸 메이트 구합니다</a></td> <td th:text="${post.date}">2023-02-03</td> </tr> </table>
th:each를 이용해 반복문을 돌면서 게시물의 제목, 게시물의 날짜를 출력해 주고.
th:href를 이용해 사용자가 게시물의 제목을 클릭하면 저번에 만들어 두었던 /post/deatliPost에 GetMapping이 전달되면서
해당 게시물의 pk값이 함께 전달될 것이다.
test
DB에서 조회한 결과대로 가장 최신의 게시물이 홈페이지 우측 하단에 정상 출력되는 모습을 확인했다.
JPA는 정말 강력한 기능 같다. DB를 손쉽게 다룰 수 있게 해 주고 객체적으로 접근도 하기 편한 거 같아서
기능을 하나하나 구현해 갈수록 JPA가 없었다면 이렇게 빨리 개발할 수 있었을까 라는 생각이 든다.
하지만 너무 의존은 하지 말아야겠다. 이 프로젝트가 끝나면 JPA 없이 구현하게 될 수도 있고 앞으로 JPA만을 이용해
개발을 한다는 보장도 없기 때문에 기초적인 지식인 쿼리나 mySQL의 기본문법들을 익혀놓아야겠다.'졸업과제 > BackEnd' 카테고리의 다른 글
Spring Security를 이용한 로그인 세션 확인. (0) 2023.03.30 Thymeleaf + Spring JPA를 이용한 게시물 좋아요 기능 (0) 2023.03.17 카테고리 지역 클릭 이후 게시물 조회, 페이징 처리 (0) 2023.03.13 Spring JPA 검색기능 구현. (0) 2023.03.12 Thymeleaf를 이용해 Option값 받아오기. (0) 2023.03.11