Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- Kernighan의 C언어 프로그래밍
- 선형대수
- 구멍가게코딩단
- 친절한SQL튜닝
- 페이징
- 깃
- 처음 만나는 AI수학 with Python
- /etc/network/interfaces
- 알파회계
- 코드로배우는스프링웹프로젝트
- 데비안
- 리눅스
- GIT
- 티스토리 쿠키 삭제
- 자료구조와함께배우는알고리즘입문
- network configuration
- 목록처리
- resttemplate
- 이터레이터
- 자료구조와 함께 배우는 알고리즘 입문
- 스프링 시큐리티
- merge
- 처음 만나는 AI 수학 with Python
- 코드로배우는스프링부트웹프로젝트
- 자바편
- 병합
- iterator
- 서버설정
- 스프링부트핵심가이드
- 네트워크 설정
Archives
- Today
- Total
bright jazz music
[bootBoard] N:1(다대일) 연관관계: 11-7. 목록화면에서 검색 처리 본문
Framework/Spring
[bootBoard] N:1(다대일) 연관관계: 11-7. 목록화면에서 검색 처리
bright jazz music 2022. 10. 12. 21:45https://github.com/hojuncha997/bootBoard
1. list.html에 아래 코드 추가
검색을 위한 폼과 버튼을 추가한다. 이 폼은 테이블 위에 존재할 것이다.
<!-- 검색을 위한 추가 -->
<form action="/board/list" method="get" id="searchForm">
<div class="input-group">
<input type="hidden" name="page" value = "1">
<div class="input-group-prepend">
<select class="custom-select" name="type">
<option th:selected="${pageRequestDTO.type == null}">-------</option>
<option value="t" th:selected="${pageRequestDTO.type =='t'}" >제목</option>
<option value="t" th:selected="${pageRequestDTO.type =='c'}" >내용</option>
<option value="t" th:selected="${pageRequestDTO.type =='w'}" >작성자</option>
<option value="tc" th:selected="${pageRequestDTO.type =='tc'}" >제목 + 내용</option>
<option value="tcw" th:selected="${pageRequestDTO.type =='tcw'}" >제목 + 내용 + 작성자</option>
</select>
</div>
<input class="form-control" name="keyword" th:value="${pageRequestDTO.keyword}">
<div class="input-group-append" id="button-addon4">
<button class="btn btn-outline-secondary btn-search" type="button">Search</button>
<button class="btn btn-outline-secondary btn-clear" type="button">Clear</button>
</div>
</div>
</form>
<!-- 검색을 위한 추가 끝-->
이전 포스팅에서 게시했던 list.html은 내가 일부 코드를 빼먹어서 오류가 발생하였다. 따라서 수정하였다.
아래는 수정한 list.html 파일의 전문이며 구동에 문제가 없었다.
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:replace="~{/layout/basic :: setContent(~{this::content} )}">
<th:block th:fragment="content">
<h1 class="mt-4">Board List Page
<span>
<a th:href="@{/board/register}">
<button type="button" class="btn btn-outline-primary">REGISTER
</button>
</a>
</span>
</h1>
<!-- 검색을 위한 추가 -->
<form action="/board/list" method="get" id="searchForm">
<div class="input-group">
<input type="hidden" name="page" value = "1">
<div class="input-group-prepend">
<select class="custom-select" name="type">
<option th:selected="${pageRequestDTO.type == null}">-------</option>
<option value="t" th:selected="${pageRequestDTO.type =='t'}" >제목</option>
<option value="t" th:selected="${pageRequestDTO.type =='c'}" >내용</option>
<option value="t" th:selected="${pageRequestDTO.type =='w'}" >작성자</option>
<option value="tc" th:selected="${pageRequestDTO.type =='tc'}" >제목 + 내용</option>
<option value="tcw" th:selected="${pageRequestDTO.type =='tcw'}" >제목 + 내용 + 작성자</option>
</select>
</div>
<input class="form-control" name="keyword" th:value="${pageRequestDTO.keyword}">
<div class="input-group-append" id="button-addon4">
<button class="btn btn-outline-secondary btn-search" type="button">Search</button>
<button class="btn btn-outline-secondary btn-clear" type="button">Clear</button>
</div>
</div>
</form>
<!-- 검색을 위한 추가 끝-->
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
<th scope="col">Writer</th>
<th scope="col">Regdate</th>
</tr>
</thead>
<tbody>
<tr th:each="dto : ${result.dtoList}">
<th scope="row">
<a th:href="@{/board/read(bno = ${dto.bno},
page= ${result.page},
type=${pageRequestDTO.type} ,
keyword = ${pageRequestDTO.keyword})}">
[[${dto.bno}]]
</a>
</th>
<td>[[${dto.title}]] ---------------- [<b th:text="${dto.replyCount}"></b>]</td>
<td>[[${dto.writerName}]] <small>[[${dto.writerEmail}]]</small></td>
<td>[[${#temporals.format(dto.regDate, 'yyyy/MM/dd')}]]</td>
</tr>
</tbody>
</table>
<!-- 페이징-->
<ul class="pagination h-100 justify-content-center align-items-center">
<li class="page-item " th:if="${result.prev}">
<a class="page-link" th:href="@{/board/list(page= ${result.start -1},
type=${pageRequestDTO.type} ,
keyword = ${pageRequestDTO.keyword} ) }" tabindex="-1">Previous</a>
</li>
<li th:class=" 'page-item ' + ${result.page == page?'active':''} " th:each="page: ${result.pageList}">
<a class="page-link" th:href="@{/board/list(page = ${page} ,
type=${pageRequestDTO.type} ,
keyword = ${pageRequestDTO.keyword} )}">
[[${page}]]
</a>
</li>
<li class="page-item" th:if="${result.next}">
<a class="page-link" th:href="@{/board/list(page= ${result.end + 1} ,
type=${pageRequestDTO.type} ,
keyword = ${pageRequestDTO.keyword} )}">Next</a>
</li>
</ul>
<!---->
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script th:inline="javascript">
var msg = [[${msg}]];
console.log(msg);
if(msg){
$(".modal").modal();
}
var searchForm = $("#searchForm");
$('.btn-search').click(function(e){
searchForm.submit();
});
$('.btn-clear').click(function(e){
searchForm.empty().submit();
});
</script>
</th:block>
</th:block>
2. BoardServiceImpl 클래스 코드 수정
getList() 일부 수정
//BoardServiceImpl.java
@Service
@RequiredArgsConstructor
@Log4j2
public class BoardServiceImpl implements BoardService {
private final BoardRepository repository; // 자동 주입 final
private final ReplyRepository replyRepository; //새롭게 추가
///...
//목록처리
@Override
public PageResultDTO<BoardDTO, Object[]> getList(PageRequestDTO pageRequestDTO) {
log.info(pageRequestDTO);
Function<Object[], BoardDTO> fn =
(en -> entityToDTO((Board)en[0], (Member)en[1], (Long)en[2]));
//Board board, Member member, Long replyCount
// Page<Object[]> result = repository.getBoardWithReplyCount(
// pageRequestDTO.getPageable(Sort.by("bno").descending()));
Page<Object[]> result = repository.searchPage(
pageRequestDTO.getType()
, pageRequestDTO.getKeyword()
, pageRequestDTO.getPageable(Sort.by("bno").descending())
);
return new PageResultDTO<>(result, fn);
}
///...
}
3. 프로젝트 구동
localhost:8080/board/list 접근
4. 검색 테스트
콘솔 로그
2022-10-12 22:39:19.728 INFO 1696 --- [nio-8080-exec-4] c.e.b.controller.BoardController : list.............PageRequestDTO(page=1, size=10, type=tcw, keyword=1)
2022-10-12 22:39:19.728 INFO 1696 --- [nio-8080-exec-4] c.e.bootboard.service.BoardServiceImpl : PageRequestDTO(page=1, size=10, type=tcw, keyword=1)
2022-10-12 22:39:19.728 INFO 1696 --- [nio-8080-exec-4] c.e.b.r.s.SearchBoardRepositoryImpl : searchPage............................
Hibernate:
select
board0_.bno as col_0_0_,
member1_.email as col_1_0_,
count(reply2_.rno) as col_2_0_,
board0_.bno as bno1_0_0_,
member1_.email as email1_1_1_,
board0_.moddate as moddate2_0_0_,
board0_.reg_date as reg_date3_0_0_,
board0_.content as content4_0_0_,
board0_.title as title5_0_0_,
board0_.writer_email as writer_e6_0_0_,
member1_.moddate as moddate2_1_1_,
member1_.reg_date as reg_date3_1_1_,
member1_.name as name4_1_1_,
member1_.password as password5_1_1_
from
board board0_
left outer join
member member1_
on (
board0_.writer_email=member1_.email
)
left outer join
reply reply2_
on (
reply2_.board_bno=board0_.bno
)
where
board0_.bno>?
and (
board0_.title like ? escape '!'
or board0_.content like ? escape '!'
or member1_.email like ? escape '!'
)
group by
board0_.bno
order by
board0_.bno desc limit ?
2022-10-12 22:39:19.731 INFO 1696 --- [nio-8080-exec-4] c.e.b.r.s.SearchBoardRepositoryImpl : [[Board(bno=102, title=Title...100, content=Content...100), Member(email=user100@aaa.com, password=11111, name=USER100), 0], [Board(bno=93, title=Title...91, content=Content...91), Member(email=user91@aaa.com, password=11111, name=USER91), 0], [Board(bno=83, title=Title...81, content=Content...81), Member(email=user81@aaa.com, password=11111, name=USER81), 1], [Board(bno=73, title=Title...71, content=Content...71), Member(email=user71@aaa.com, password=11111, name=USER71), 2], [Board(bno=63, title=Title...61, content=Content...61), Member(email=user61@aaa.com, password=11111, name=USER61), 0], [Board(bno=53, title=Title...51, content=Content...51), Member(email=user51@aaa.com, password=11111, name=USER51), 0], [Board(bno=43, title=Title...41, content=Content...41), Member(email=user41@aaa.com, password=11111, name=USER41), 0], [Board(bno=33, title=Title...31, content=Content...31), Member(email=user31@aaa.com, password=11111, name=USER31), 1], [Board(bno=23, title=Title...21, content=Content...21), Member(email=user21@aaa.com, password=11111, name=USER21), 1], [Board(bno=21, title=Title...19, content=Content...19), Member(email=user19@aaa.com, password=11111, name=USER19), 0]]
Hibernate:
select
count(distinct board0_.bno) as col_0_0_
from
board board0_
left outer join
member member1_
on (
board0_.writer_email=member1_.email
)
left outer join
reply reply2_
on (
reply2_.board_bno=board0_.bno
)
where
board0_.bno>?
and (
board0_.title like ? escape '!'
or board0_.content like ? escape '!'
or member1_.email like ? escape '!'
)
2022-10-12 22:39:19.732 INFO 1696 --- [nio-8080-exec-4] c.e.b.r.s.SearchBoardRepositoryImpl : COUNT: 20
where 절이 처리되는 방식을 주목할 것
'Framework > Spring' 카테고리의 다른 글
RestTemplate 02 : 커넥션 풀(connection pool) 추가 (0) | 2023.03.06 |
---|---|
RestTemplate 01 : 파라미터 없는 GET 요청 (0) | 2023.03.02 |
[bootBoard] N:1(다대일) 연관관계: 11-6. JPQLQuery로 Page<Object[]> 처리: sort 처리 / count 처리 (0) | 2022.10.11 |
[bootBoard] N:1(다대일) 연관관계: 11-5. JPQLQuery로 Page<Object[]> 처리: 검색 조건의 처리 (0) | 2022.10.11 |
[bootBoard] N:1(다대일) 연관관계: 11-4. JPQLQuery로 Page<Object[]> 처리 (0) | 2022.10.11 |
Comments