Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
more
Archives
Today
Total
관리 메뉴

게으른 완벽주의자의 개발자 도전기

[board] 게시판 목록 페이지 조회(게시판 목록, 페이지 수 표시, 게시글 검색, a태그) 본문

Spring Boot

[board] 게시판 목록 페이지 조회(게시판 목록, 페이지 수 표시, 게시글 검색, a태그)

머리방울 2022. 9. 12. 15:13

1. VO 만들기 (상속 사용하기)

1) BoardVO

 

2) PageVO (게시글 페이지)

 생성자 만들기
    public PageVO() {
    	nowPage = 1;
    	displayCnt= 15;
    	displayPageCnt = 10;
    }
  
    public void setPageInfo() {
    	 		1  2  3  4  5 next
    	 prev 6  7  8  9  10 next
    	화면에 보이는 마지막 페이지 번호  
    	Math.ceil 올림 함수 ceil이 double로 받아서 int로 바꿔준 것 
    	endPage = displayPageCnt * (int)Math.ceil(nowPage/(double)displayPageCnt);
    	beginPage = (endPage - displayPageCnt) +1;
    	
        전체 페이지 수 (만약 100개 게시물 있다면 / 10개 페이지) 
        둘다 정수라서 하나 실수로 만듦(Math.ceil)
    	int totalPageCnt= (int)Math.ceil(totalDataCnt /(double)displayCnt);
    	
    	next 버튼 표시 유무 
    	if(endPage <totalPageCnt) {
    		next = true;
    	}
    	else {
    		next = false;
    		endPage = totalPageCnt;
    	}
    
    	prev 버튼 표시 유무 
    	prev = beginPage == 1 ? false : true;

    	페이지별 시작 게시글 번호, 마지막 게시글 번호
    	startNum = (nowPage -1) *  displayCnt +1;
    	endNum = nowPage * displayCnt; 
    }

3) SearchVO (게시글 검색 시 사용할 것)

 

2. mapper

1. 게시글 목록 조회
<select id="selectBoardList" resultMap="board">
 1) 게시글 페이지번호
	SELECT ROW_NUM
		, BOARD_NUM
		, TITLE
		, WRITER
		, CREATE_DATE
	FROM
	(
	SELECT ROWNUM AS ROW_NUM
		, BOARD_NUM
		, TITLE
		, WRITER
		, CREATE_DATE
	FROM(
	SELECT BOARD_NUM
		, TITLE
		, WRITER
		, TO_CHAR(CREATE_DATE, 'YYYY.MM.DD') AS CREATE_DATE
	FROM SPRING_BOARD


    2) 필요시에 따라 where절 실행되도록 해야하기 때문에 if문 사용
	 검색창에 타이틀이 null 아니고 타이틀이 빈문자열이 아니라면
     (★f5 눌렀을 때 또는 검색창에 아무것도 안넣고 검색 시 빈문자 가져감
     그때는 IF절 실행될 필요가 없기 때문이다.)
    <if test="searchValue != null and !searchValue.equals('')"> 
	
	(★ #{}쓰면 자동으로 'TITLE' 붙는다. 홀따옴표 없애야하니까 ${}쓰면 TITLE)
    (HTML에 "${boardVO.searchKeyword == 'TITLE'} 이렇게 작성해뒀기 때문이다.)
   
   3) 대소문자 관계없이 검색하기
	WHERE UPPER(${searchKeyword}) LIKE '%'||UPPER(#{searchValue})||'%' 
	OR LOWER(${searchKeyword}) LIKE '%'||LOWER(#{searchValue})||'%'
	
	</if>
	ORDER BY BOARD_NUM DESC
    ) 
)

4) 행 시작과 끝
( &gt; -> greater than / &lt; -> less than )
WHERE ROW_NUM &gt;=#{startNum} AND ROW_NUM &lt;=#{endNum}     

</select>

 2. 게시글 전체 데이터 수 (PK는 NULL 없으니까)
<select id="selectBoardCnt" resultType="int">

SELECT COUNT(BOARD_NUM) 
FROM SPRING_BOARD

</select>


ROWNUM : 조회된 행번호

SELECT할 때마다 계속 ROWNUM 부여된다. 그래서 인라인 뷰

FROM 절에서 SELECT문을 작성하여 먼저 정렬 한 후에  

인라인뷰 SELECT문에서 특정한(별칭 넣은) NOWNUM 도출하는 쿼리문 작성하면

ROWNUM을 추출할 수있다.

 

3. 인터페이스 ServiceImpl

게시글 목록조회
	List<BoardVO> selectBoardList(BoardVO boardVO);
	
게시글 총 개수 조회
	int selectBoardCnt();
@Service("boardService")
public class BoardServiceImpl implements BoardService {

	@Autowired	
	SqlSessionTemplate sqlSession;  
    (run하면 자동으로 아래의 객체가 만들어 진다(IOC))
	(SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(); )


	게시글 목록조회
	스프링은 자동 커밋이다 (insert, update, select, delete 뭐든 자동 커밋)
	@Override
	public List<BoardVO> selectBoardList(BoardVO boardVO) {
		return sqlSession.selectList("boardMapper.selectBoardList", boardVO);
	}
	
	게시글 총 개수 조회
	@Override
	public int selectBoardCnt() {
		return sqlSession.selectOne("boardMapper.selectBoardCnt");
	}

 

4. controller

@Controller
@RequestMapping("/board")	
public class BoardController {
	@Resource(name = "boardService") 
    boardService라는 이름으로 만들어진 객체 로드해서 의존성 주입
	@Resource는 boardService라는 변수명(이름으로 접근)으로 데이터 가져온다
	즉, 객체 자료형 두가지일 때 특정한거 가져 오고자 할 때 사용한다
	
    private BoardService boardService;
	
	게시글 목록 조회
	@RequestMapping("/list")  
    RequestMapping - post, get 둘 다 받음 
	
    public String selectBoardList(BoardVO boardVO, Model model) {
		
		전체 데이터 수 
		int totalCnt = boardService.selectBoardCnt();
		
		페이지 정보 셋팅
		boardVO.setTotalDataCnt(totalCnt);
		boardVO.setPageInfo();		
		
		데이터 내보내기
		model.addAttribute("boardList", boardService.selectBoardList(boardVO));
		
        경로 기본은 template에서 시작
		return "board/board_list";		
       
	}

 

5. html

<body>

<h2 align="center">
게시글 목록
</h2>

1. 검색정보 데이터 보내기 
<form action="/board/list" method="post">
	<div class="search">
	<select name="searchKeyword">
	(mapper #{searchKeyword}에 컬럼명이 들어감)
		<option value="TITLE" th:selected="${boardVO.searchKeyword == 'TITLE'}">
        제목</option>
		<option value="WRITER" th:selected="${boardVO.searchKeyword == 'WRITER'}">
        작성자</option>
		<option value="CONTENT" th:selected="${boardVO.searchKeyword == 'CONTENT'}">
        내용</option>
	</select>
		(검색창에 해당 글자 남아있도록 하기 위해서 th:value 사용)
		<input type="text" name="searchValue" th:value="${boardVO.searchValue}">
		<input type="submit" value="검색"> <br>
	</div>
</form>

2. 게시물 목록
	<table>
	<tr>
		<td>No</td>
		<td>제목</td>
		<td>작성자</td>
		<td>작성일</td>
	</tr>
	(thymeleaf에서 함수 사용 시 #list, #String 이런식으로 사용함)
    
	<th:block th:if="${#lists.size(boardList)== 0}">
		<tr>
			<td colspan="4">게시글이 없습니다.</td>
		</tr>
	</th:block>
	
	<th:block th:unless="${#lists.size(boardList)== 0}">
		<tr th:each="board : ${boardList}">
			<td th:text="${board.boardNum}"></td>
			<td>
			(★<a th:href="@{이동할 경로 (데이터1 = ${ }, 데이터2 = ${ })}">  )
	<a th:href="@{/board/boardDetail(num=${board.boardNum})}" th:text="${board.title}">
    </a>
			</td>
			<td th:text="${board.writer}"></td>
			<td th:text="${board.createDate}"></td>
		</tr>
	</th:block>

	</table>
	
    3. 페이지 번호 영역 
	<div align="center">
    	
        prev 버튼
		<th:block th:if="${boardVO.prev}">
			<a th:text="prev" th:href="@{/board/list(nowPage=${boardVO.beginPage - 1})}"></a>	
		</th:block>
		
        페이지 번호
		<th:block th:each="pageNum : ${#numbers.sequence(boardVO.beginPage, boardVO.endPage)}">
			<a th:text="${pageNum}" th:href="@{/board/list(nowPage=${pageNum})}"></a>
		</th:block>
		
        next 버튼
		<th:block th:if="${boardVO.next}">
			<a th:text="next" th:href="@{/board/list(nowPage=${boardVO.endPage + 1})}"></a>	
		</th:block>
	</div>
	
    4.글쓰기 버튼
	<div align="center">
		<input type="button" value="글쓰기" onclick="location.href='/board/regForm';">
	</div>

</body>

 

a태그로 데이터 넘기기

<a th:href="@{이동할 경로 (데이터1 = ${ }, 데이터2 = ${ })}"> 
<a th:href="@{/board/boardDetail(num=${board.boardNum})}"
th:text="${board.title}" ></a>

 특정 url로 이동
<a th:href="@{https://www.google.co.kr/}"> 페이지 이동 </a>

 현재 서버 내에서 이동  
<a th:href="@{/board/list}">게시글 List</a>

 파라미터를 넘길 때 
<a th:href="@{/board/detail(boardNum = ${board.boardNum})}">글 상세보기</a>

 파라미터를 여러 개 넘길 때 
<a th:href="@{/board/detail(boardNum = ${board.boardNum}
, writer = ${board.writer}})}">글 상세보기</a>