※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다.

개발 환경
사용언어 : Java
프레임 워크 : Spring boot
통합 개발 환경 : IntelliJ
데이터베이스 : MariaDB
뷰 템플릿(템플릿 엔진) : Thymeleaf
프로젝트 진행 순서
[Spring boot] 게시판 만들기 (1주차 : 개발 환경 세팅, 프로젝트 생성)
※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다. 개발 환경사용언어 : Java프레임 워크 : Spring boot통합 개발 환경 : IntelliJ데이터베이스 : MariaDB뷰 템플릿(템플릿 엔진)
zprograming.tistory.com
1. 개발 환경 세팅
- IntelliJ Community 다운로드
- MariaDB 다운로드
- MySQL Workbench 다운로드
2. 프로젝트 생성
- IntelliJ Community에서 Spring Boot 프로젝트 생성 (https://start.spring.io/)
- MariaDB Database(스키마) 생성
[Spring boot] 게시판 만들기 (2주차 : DB 테이블 생성, 게시글 작성폼 생성, 글 작성 처리, 게시글 리
※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다. 개발 환경사용언어 : Java프레임 워크 : Spring boot통합 개발 환경 : IntelliJ데이터베이스 : MariaDB뷰 템플릿(템플릿 엔진)
zprograming.tistory.com
3. 게시물 작성
- db에 board 테이블 및 필드 생성
- 게시글 작성 폼 생성
4. 게시물 리스팅
[Spring boot] 게시판 만들기 (3주차 : 게시글 상세 페이지, 게시글 삭제 및 수정, 메시지 띄우기, 파
※ [한코딩] 게시판 만들기 유튜브를 참고하여 진행하는 프로젝트입니다. 개발 환경사용언어 : Java프레임 워크 : Spring boot통합 개발 환경 : IntelliJ데이터베이스 : MariaDB뷰 템플릿(템플릿 엔진) : Thy
zprograming.tistory.com
5. 게시물 삭제
- 게시글 상세 페이지
6. 게시물 수정
- 게시글 수정
- 메시지 띄우기
7. 파일 업로드
8. 페이징 처리
@PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable
Controller의 boardList의 매개변수로 pageable을 추가해준다.
public Page<Board> boardList(Pageable pageable) {
return boardRepository.findAll(pageable); // Board 라는 class가 담긴 LIst 반환
}
boardService로 pageable을 넘겨주고 Page<Board> 클래스로 리턴하는 코드로 수정한다.

역순으로 정렬된 리스트 화면으로 변경되었다.

list?page=2로 입력하면 3번째 페이지가 화면에 나타난다.
- 페이징 블럭 출력하기
필요한 변수
- nowPage : 현재 페이지
- startPage : 블럭에서 보여줄 시작 페이지
- endPage : 블럭에서 보여줄 마지막 페이지
타임리프 문법
- th:text : 태그 안에 데이터를 출력
- th:each : 반복문
- th:each = "${number:#number(시작 번호, 끝번호)}"
>> 시작 번호에서 끝번호까지 반복
int nowPage = list.getPageable().getPageNumber() + 1;
int startPage = Math.max(nowPage -4, 1); // 1보다 작은 경우 1이 크기 때문에 1 반환
int endPage = Math.min(nowPage + 5, list.getTotalPages());
model.addAttribute("nowPage", nowPage);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
boardService에 @GetMappeing("/board/list")에 위의 코드를 추가한다.
시작 페이지는 1페이지보다 작으면 안 되니까 Math.max로 비교해주고,
마지막 페이지는 총 페이지를 초과하면 안 되니까 getTotalPages() 를 사용한다.
model.addAttribute()로 thymeleaf로 변수를 다 넘겨준다.
<th:block th:each="page: ${#numbers.sequence(startPage, endPage)}">
<a th:if="${page != nowPage}" th:href="@{/board/list(page = ${page-1})}" th:text = "${page}"></a>
<strong th:if="${page == nowPage}" th:text = "${page}" style = "color : red"></strong>
</th:block>
boardlist.html 의 </table>태그 밑에 위의 코드를 작성하고 실행하면,

페이지버튼이 정상적으로 출력되며, 페이지 클릭시 빨간색으로 강조된다.
9. 게시판 검색 기능
JPA Reposiory
findBy(컬럼 이름) : 컬럼에서 키워드를 넣어서 찾겠다.
* 정확하게 키워드가 일치하는 데이터만 검색
@Repository
public interface BoardRepository extends JpaRepository<Board, Integer> { // extends 상속받음. JpaRepository를 상속받아 타입지정.
Page<Board> findByTitleContaining(String searchKeyword, Pageable pageable);
}
BoardRepository 인터페이스를 위와 같이 수정한다.
// 키워드 검색 기능
public Page<Board> boardSearchList(String searchKeyword, Pageable pageable) {
return boardRepository.findByTitleContaining(searchKeyword, pageable);
}
BoardService에 키워드 검색 기능을 추가한다.
@GetMapping("/board/list")
public String boardList(Model model,
@PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
String searchKeyword) { // 데이터를 담아서 페이지로 보낼 때 Model 사용
Page<Board> list = null;
if(searchKeyword == null) {
list = boardService.boardList(pageable);
} else {
list = boardService.boardSearchList(searchKeyword, pageable);
}
int nowPage = list.getPageable().getPageNumber() + 1;
int startPage = Math.max(nowPage -4, 1); // 1보다 작은 경우 1이 크기 때문에 1 반환
int endPage = Math.min(nowPage + 5, list.getTotalPages());
model.addAttribute("list", boardService.boardList(pageable)); // list라는 이름으로 보낼 건데, boardService에 boardList() >> 반환된 리스트를 list 라는 이름으로 넘기겠다는 뜻.
model.addAttribute("nowPage", nowPage);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
return "boardlist";
}
BoardController에 boardList 메서드에 searchKeyword 매개변수를 추가해준 후,
searchKeyword가 있을 경우와 없을 경우를 다르게 처리하기 위해 if문을 작성한다.
<th:block th:each="page: ${#numbers.sequence(startPage, endPage)}">
<a th:if="${page != nowPage}" th:href="@{/board/list(page = ${page-1}, searchKeyword = ${param.searchKeyword})}" th:text = "${page}"></a>
<strong th:if="${page == nowPage}" th:text = "${page}" style = "color : red"></strong>
</th:block>
list?searchKeyword=11 로 테스트 검색시 페이지 이동하면 검색한 Keyword가 사라짐
그 처리를 해주기 위해 boardlist.html의 a태그 안에 searchKeyword = ${param.searchKeyword} 를 추가했다.
<form th:action="@{/board/list}" method="get">
<input type ="text" name="searchKeyword">
<button type="submit">검색</button>
</form>
실제로 키워드를 검색하기 위한 form 을 html에 작성한다.

/board/list 에 접속하면 검색 박스와 버튼이 생긴 걸 확인할 수 있고,

11을 검색하면 키워드가 포함된 게시글이 정상적으로 검색된다!!
Trouble Shooting
1. /board/list?searchKeyword=11 테스트시 출력 오류
여기서 searchKeyword가 있는 경우에도 boardService.boardList(pageable)로 다시 전체 리스트를 넣고 있어서, 실제 검색 결과가 아닌 전체 목록이 화면에 나올 수 있음. 아래와 같이 코드 수정.
model.addAttribute("list", list);
4주차 소감
게시판 만들기를 완료하였다!!!!!
간단한 기능들이지만, 각 파일들이 서로 어떤식으로 연관되어 동작하는지 처리과정을 알 수 있어서 매우 유익한 시간이었다.
다만... 아직 정확한 동작방법이나 메소드, 라이브러리 등 익숙하지 않은 것들이 많아서 배운 내용을 바탕으로 다른 개인 프로젝트를 진행하며 공부해봐야겠다는 생각을 했다! (특히 매개변수와 인수로 주고받는 부분들이 너무 헷갈린다 ㅠ)
시간이 된다면 게시판만들기 과정을 처음부터 끝까지 한번 더 복습하면 좋을 것 같다는 생각을 했다.
다 끝내서 뿌듯하다 ㅎ,ㅎ
'프로젝트 > 게시판 만들기' 카테고리의 다른 글
| [Spring boot] 게시판 만들기 (3주차 : 게시글 상세 페이지, 게시글 삭제 및 수정, 메시지 띄우기, 파일 업로드) (3) | 2025.05.03 |
|---|---|
| [Spring boot] 게시판 만들기 (2주차 : DB 테이블 생성, 게시글 작성폼 생성, 글 작성 처리, 게시글 리스트) (8) | 2025.04.09 |
| [Spring boot] 게시판 만들기 (1주차 : 개발 환경 세팅, 프로젝트 생성) (3) | 2025.04.05 |