본문 바로가기
클론코딩

LMS Web 클론코딩 12 (검색기능 구현, Date 나타내기)

by zho 2024. 2. 2.

2024/2/2

 

검색기능을 구현하기 위해 어떻게 구현할지에 대해서 생각을 먼저 해보았다. 일단 두 가지 방법을 생각해 봤는데 첫 번째는 검색어를 입력하면 화면 전체를 다시 불러와서 해당 검색어가 있는 post-list를 course페이지에서 보여주는 것이고, 두 번째는 ajax를 이용하여 비동기 방식으로 처리하여 바로 post-list를 보여주는 방법이다.

 

첫 번째 방법이 좀 더 쉬울 것 같아 일단 첫 번째 방법을 선택했다. 

sdf를 검색한 결과

 

 

검색기능구현


1. Course 페이지

<div class="search-bar">
    <form action="lms/search-posts" method="get" class="search-form">
        <input type="text" id="search-input" name="title" placeholder="Title" />
        <button type="submit" id="search-button" class="search-btn">Search</button>
    </form>
</div>

 

form action으로 감싸주어 search 버튼을 눌렀을 때, get요청이 lms/search-posts로 요청되도록 구현한다.

 

2. PostController

@GetMapping("lms/search-posts")
public String searchPosts(@RequestParam(required = false) String title, Model model) {
    if (title != null && !title.isEmpty()) {
        List<Post> posts = postService.findByTitleContaining(title);
        model.addAttribute("posts", posts);
    } else {
        model.addAttribute("posts", Collections.emptyList());
    }
    return "course";
}

 

위 Search 버튼을 눌렀을때 Get요청을 관리하는 Controller이다. 

if (title != null && !title.isEmpty()) 구문은 title 파라미터가 null이 아니고 빈 문자열도 아닐 경우에만 검색 로직을 수행하도록 한다. 이 경우, postService.findByTitleContaining(title)을 호출하여 제목에 title을 포함하는 모든 포스트를 검색하고 결과를 model 객체에 추가한다.

else 구문에서는 title 파라미터가 없거나 빈 문자열인 경우 빈 리스트를 model에 추가한다. 이는 검색 결과가 없을 때 뷰에서 빈 리스트를 처리할 수 있도록 하기 위함이다. 

 

3. PostService

public List<Post> findByTitleContaining(String title) {
    return postRepository.findByTitleContaining(title);
}

4. PostRepository 기능 구현

    private final JdbcTemplate jdbcTemplate;

    public JdbcPostRepository(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    private final RowMapper<Post> postRowMapper = (rs, rowNum) -> {
        Post post = new Post();
        post.setId(rs.getLong("id"));
        post.setTitle(rs.getString("title"));
        post.setContent(rs.getString("content"));
        post.setDate(rs.getDate("date"));
        return post;
    };

@Override
public List<Post> findByTitleContaining(String title) {
    String sql = "SELECT * FROM qna WHERE title LIKE ?";
    return jdbcTemplate.query(sql, new Object[]{"%" + title + "%"}, postRowMapper);
}

 

qna 테이블에서 title이 속한 데이터들을 찾아준다.

 

 

Date 나타내기 (Tymeleaf)


1. Controller

@PostMapping("lms/savePost")
public String savePost(@RequestParam String title, @RequestParam String content) {
    LocalDateTime now = LocalDateTime.now();
    Timestamp timestamp = Timestamp.valueOf(now);
    Post post = new Post();
    post.setTitle(title);
    post.setContent(content);
    post.setDate(timestamp);
    postService.join(post);
    return "redirect:/course";
}

다음과 같이 Date를 설정해주고 join 해준다.

 

2. Repository 구현

@Override
public Post save(Post post) {
    SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
    jdbcInsert.withTableName("qna").usingGeneratedKeyColumns("id");
    Map<String, Object> parameters = new HashMap<>();
    parameters.put("title", post.getTitle());
    parameters.put("content", post.getContent());
    parameters.put("date", post.getDate());
    Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
    post.setId(key.longValue());
    return post;
}

 

3. 화면 보여주기

<div class="post-date" th:text="'Date: ' + ${#dates.format(post.date, 'MMMM d h:mm a')}">Post Date</div>

 

위와 같이 설정하면 Date: February 2 12:00 AM 이런 포맷으로 출력하게 된다.

728x90