스프링

 

참조 :

★스프링부트 JPA 페이징 및 검색 처리, Jsp ,Thymeleaf

 

 

 

 

controller

    //상세보기
    @GetMapping("/board/{id}")
    public String findById(@PathVariable Long id,  @AuthenticationPrincipal PrincipalDetails principal, 
			@RequestParam(value = "page",defaultValue ="1", required = false) 
			Optional<Integer> page,    		
    		Model model) {
    
    	int pageSize=5;
        Pageable pageable= PageRequest.of(page.isPresent()? page.get()-1 :0, pageSize);    	
        Page<Reply>  replyList= replyService.replyList(pageable);        
        Pagination pagination =new Pagination((int)replyList.getTotalElements(),  page.get(),  pageSize , 5);
    	
        
    	model.addAttribute("auth", principal.getUser());
    	model.addAttribute("board", boardService.boardDetail(id));    	
    	model.addAttribute("replyList", replyList);
    	model.addAttribute("pagination", pagination);
    	return "board/detail";
    }
    

 

 

service

@Service
@RequiredArgsConstructor
@Transactional
public class ReplyService {
	
	private final ReplyRepository  replyRepository;
	
	public Page<Reply> replyList(Pageable pageable) {			
		return replyRepository.findAll(pageable);
	}
}

 

view

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout=http://www.ultraq.net.nz/thymeleaf/layout
      layout:decorate="~{layouts/layout1}"      
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

<div layout:fragment="content">


    <div class="container">
				<button type="button"  class="btn btn-secondary"  onclick="history.back()">돌아가기</button>
			
		<!-- 	     인증시 사용된 객체에 대한 정보
		        <b>Authenticated DTO:</b>
		        <div sec:authentication="principal"></div>
		
		        인증시 사용된 객체의 Username (ID)
		        <b>Authenticated username:</b>
		        <div sec:authentication="name"></div>
		
		        객체의 권한te
		        <b>Authenticated user role:</b>
		        <div sec:authentication="principal.authorities"></div>
		         -->

			<th:block  th:if="${board.user.username ==auth.Username}">
				<a th:href="@{'/board/'+${board.id}+'/updateForm'}"	class="btn btn-warning">수정</a>
				<button id="btn-delete"	class="btn btn-danger">삭제</button>
			</th:block>	
				<br><br>
	
			<div class="mb-5">
			글번호 : <span id="id" class="mr-5"><i>[[${board.id}]]</i></span>
			작성자 : <span><i>[[${board.user.username}]]</i></span>
			</div>
		
     	
			<div class="form-group mb-5">
		 		[[${board.title}]]			
			</div>
	
			<hr>
			<div class="form-group">		 		
		 		<th:block  th:utext="${board.content}"></th:block>					
			</div>
			<hr>
		
		
		<div class="card">
				<div class="card-body">
					<textarea id="reply-content"    class="form-control" rows="1" cols=""></textarea>
				</div>		
				<div class="card-footer text-center">
					 <input type="hidden" name="boardId" id="boardId" th:value="${board.id}" >
					<button id="btn-reply-save" class="btn btn-primary">등록</button>
				</div>	
		</div>
		<hr>
		
		
		
		<div class="card mt-5">
			<div class="card-header">댓글 총  [[${pagination.listCnt}]] 개</div>
			<ul id="reply--box" class="list-group">
			
		<th:block   th:each ="reply, status : ${replyList.content}"  >
			  <li th:id="'reply-'+${reply.id}"   class="list-group-item d-flex justify-content-between">
			  	<div>[[${reply.content}]]</div>
			  	<div class="d-flex ">
			  		<div>작성자 : [[${reply.user.username}]]</div>

				  	<th:block th:if="${reply.user.id ==auth.id}">
					  		<div class="ml-3">
					  		<button 
					  		  th:data-boardId='${board.id}'
					  		  th:data-replyId='${reply.id}'
					  		  class="btn btn-danger btn-sm replyDelete">삭제</button>
					  		   </div>
					 </th:block>		  
			  		  				  		
			  	</div>			  
			  </li>
			  
		</th:block>		 	  
			</ul>
		</div>
		
			<ul class="pagination justify-content-center mt-5" th:if="${pagination.listCnt>0}">
				<th:block th:if="${not replyList.first}">
					<li class="page-item" ><a class="page-link" th:href="@{&page=1}">≪</a></li>
					<li class="page-item" ><a class="page-link" th:href="@{'?page='+${pagination.prevPage}}">&lt;</a></li>
				</th:block>
				
				<li class="page-item" th:each="page : ${ #numbers.sequence(pagination.startPage, pagination.endPage)  }" 
					th:classappend="${page eq pagination.curPage} ? 'active':'' ">
				<a class="page-link" th:href="@{'?page=' +${page}}">[[${page}]]</a>
				</li>
		
				<th:block th:if="${not replyList.last}">
					<li class="page-item"><a class="page-link" th:href="@{'?page=' + ${pagination.nextPage}}">&gt;</a></li>
					<li class="page-item"><a class="page-link" th:href="@{'?page=' + ${replyList.totalPages}}">≫</a></li>
				</th:block>
			</ul>

		
		
    </div>


</div>


<th:block layout:fragment="script">
<script th:src="@{/js/board.js}"></script>
    <script>
      $('.summernote').summernote({
        placeholder: '내용을 입력해 주세요.',
        tabsize: 3,
        height: 300,
      });
    </script>

</th:block>

</html>

 

 

 

Pagination

@Data
@ToString
public class Pagination {

	/** 한 페이지당 게시글 수 **/
	private int pageSize = 10;

	/** 한 블럭(range)당 페이지 수 **/
	private int rangeSize = 10;

	/** 현재 페이지 **/
	private int curPage = 1;

	/** 현재 블럭(range) **/
	private int curRange = 1;

	/** 총 게시글 수 **/
	private int listCnt;

	/** 총 페이지 수 **/
	private int pageCnt;

	/** 총 블럭(range) 수 **/
	private int rangeCnt;

	/** 시작 페이지 **/
	private int startPage = 1;

	/** 끝 페이지 **/
	private int endPage = 1;

	/** 시작 index **/
	private int startIndex = 0;

	/** 이전 페이지 **/
	private int prevPage;

	/** 다음 페이지 **/
	private int nextPage;

	
	public Pagination(int listCnt, int curPage, int pageSize , int rangeSize ) {
		this.pageSize=pageSize;
		this.rangeSize=rangeSize;
		/**
		 * 페이징 처리 순서 1. 총 페이지수 2. 총 블럭(range)수 3. range setting
		 */
		
		// 총 게시물 수와 현재 페이지를 Controller로 부터 받아온다.
		/** 현재페이지 **/
		setCurPage(curPage);
		/** 총 게시물 수 **/
		setListCnt(listCnt);

		/** 1. 총 페이지 수 **/
		setPageCnt(listCnt);
		/** 2. 총 블럭(range)수 **/
		setRangeCnt(pageCnt);
		/** 3. 블럭(range) setting **/
		rangeSetting(curPage);

	}

	public void setPageCnt(int listCnt) {
		this.pageCnt = (int) Math.ceil(listCnt * 1.0 / pageSize);
	}

	public void setRangeCnt(int pageCnt) {
		this.rangeCnt = (int) Math.ceil(pageCnt * 1.0 / rangeSize);
	}

	public void rangeSetting(int curPage) {

		setCurRange(curPage);
		this.startPage = (curRange - 1) * rangeSize + 1;
		this.endPage = startPage + rangeSize - 1;

		if (endPage > pageCnt) {
			this.endPage = pageCnt;
		}

		this.prevPage = curPage - 1;
		this.nextPage = curPage + 1;
	}

	public void setCurRange(int curPage) {
		this.curRange = (int) ((curPage - 1) / rangeSize) + 1;
	}




}

 

 

소스 : 

https://github.com/braverokmc79/Springboot-JPA-Blog

 

 

 

 

2번째 예

 

BoardRepository

import com.godcoder.myhome.model.Board;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface BoardRepository extends JpaRepository<Board, Long> {



    Page<Board> findByTitleContainingOrContentContaining(String title,  String content, Pageable pageable);


}

 

 

Controller

@GetMapping("/list")
public String list(Model model,
                   @RequestParam(value = "page",defaultValue ="1", required = false) Optional<Integer> page,
                 @RequestParam(required = false, defaultValue = "")  String searchText
){
  //  List<Board> boards= boardRepository.findAll(Sort.by(Sort.Direction.DESC, "id"));
    int pageSize=3;
    Sort sort1=Sort.by("id").descending();
    Pageable pageable=PageRequest.of(page.isPresent() ? page.get()-1 :0, pageSize,  sort1);

    //Page<Board> boards= boardRepository.findAll(pageable);
    Page<Board> boards= boardRepository.findByTitleContainingOrContentContaining(searchText, searchText,pageable);
    int startPage=Math.max(1, boards.getPageable().getPageNumber() - 4);
    int endPage=Math.min(boards.getTotalPages(), boards.getPageable().getPageNumber()+4);

    model.addAttribute("startPage", startPage);
    model.addAttribute("endPage", endPage);
    model.addAttribute("num", boards.getTotalElements()- ((page.get()-1)*pageSize ));
    model.addAttribute("boards" , boards);
    return "board/list";
}

 

 

html

<main role="main" class="container">
    <div class="starter-template">
        <h1>게시판</h1>
    </div>

    <div>총 건수 : <span th:text="${boards.getTotalElements}"></span></div>

    <form class="form-inline d-flex justify-content-end">
        <div class="form-group mx-sm-3 mb-2">
            <label for="searchText" class="sr-only">검색</label>
            <input type="search" class="form-control" id="searchText" name="searchText" th:value="${param.searchText}">
        </div>
        <button type="submit" class="btn btn-light mb-2">검색</button>
    </form>


    <table class="table table-striped">
        <thead>
        <tr>
            <th scope="col">번호</th>
            <th scope="col">제목</th>
            <th scope="col">내용</th>
        </tr>
        </thead>
        <tbody>

        <tr th:each="board , status:${boards}" >
            <th  th:text="${num - status.index}">아이디</th>
            <td>
                <a th:href="@{/board/form(id=${board.id})}" th:text="${board.title}"> </a>
            </td>
            <td  th:text="${board.content}">Otto</td>
        </tr>

        </tbody>
    </table>





    <nav aria-label="Page navigation example">
        <ul class="pagination justify-content-center">

            <li class="page-item" th:classappend="${1 == boards.pageable.pageNumber+1} ?'disabled':''" >
                <a class="page-link" th:href="@{/board/list(page=${boards.pageable.pageNumber}, searchText=${param.searchText} ) }">Previous</a>
            </li>

            <li class="page-item" th:classappend="${i == boards.pageable.pageNumber+1} ?'disabled':''"
                th:each="i : ${#numbers.sequence(startPage, endPage)}" >
                <a class="page-link" th:href="@{/board/list(page=${i} , searchText=${param.searchText}  ) }" th:text="${i}">1</a>
            </li>


            <li class="page-item" th:classappend="${boards.totalPages == boards.pageable.pageNumber+1} ?'disabled':''" >
                <a class="page-link" th:href="@{/board/list(page=${boards.pageable.pageNumber + 2} , searchText=${param.searchText} ) }" >Next</a>
            </li>
        </ul>
    </nav>



    <div class="text-right">
        <a type="button" class="btn btn-primary" th:href="@{/board/form}" >쓰기</a>
    </div>
</main><!-- /.container -->

 

 

소스 :https://github.com/braverokmc79/spring-boot-jpa-web-release

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

조막손이 달걀 도둑질한다 , 자기의 능력 이상의 일을 하려고 할 때 이르는 말.

댓글 ( 5)

댓글 남기기

작성