Url.java 수정
package com.board.common;

/* api url 정의 */
public final class Url {
	public static final String TILES_ROOT = "/tiles/view";
	public static final String TILES_SINGLE = "/tiles/single";
	public static final String TILES_AJAX = "/tiles/ajax";
	
	/* 로그인 */
	public static final class AUTH {
		
		/* 로그인 url */
		public static final String LOGIN = "/auth/login";
		
		/* 로그인 jsp */
		public static final String LOGIN_JSP = TILES_SINGLE + "/auth/login";
		
		/* 회원가입 url */
		public static final String JOIN = "/auth/join";
		
		/* 회원가입 jsp */
		public static final String JOIN_JSP = TILES_ROOT + "/auth/join";
	
		/* 사용자 등록 */
		public static final String INSERT_USER = "/auth/insertUser";
		
		/* 로그인 인증 요청 */
		public static final String LOGIN_PROC = "/auth/login-proc";
		
		/* 로그아웃 요청 */
		public static final String LOGOUT_PROC = "/auth/logout-proc";
		
	}
	
	/* 메인 화면 */
	public static final class MAIN {
		
		public static final String _MAIN_AJAX_ROOT_PATH = "/main/ajax";
		
		/* 메인 url */
		public static final String MAIN = "/";
		
		/* 메인 jsp */
		public static final String MAIN_JSP = TILES_ROOT + "/main/list";
		
		/* 메인 리스트 ajax */
		public static final String MAIN_LIST_AJAX = _MAIN_AJAX_ROOT_PATH + "/list-view";
		
		/* 메인 글쓰기 */
		public static final String MAIN_WRITE = "/board/write";
		
		/* 메인 글쓰기 jsp */
		public static final String MAIN_WRITE_JSP = TILES_ROOT + "/main/write";
		
		/* 메인 수정화면 */
		public static final String MAIN_UPDATE = "/board/update";
		
		/* 메인 글쓰기 jsp */
		public static final String MAIN_UPDATE_JSP = TILES_ROOT + "/main/update";
		
		/** 게시판 삭제 */
		public static final String MAIN_DELETE = "/board/delete";
		
	}
	
}

 

MainController.java 수정
package com.board.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.board.common.CoTopComponent;
import com.board.common.Constants;
import com.board.common.Url;
import com.board.common.Url.MAIN;
import com.board.dao.MainMapper;
import com.board.service.MainService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MainController extends CoTopComponent {

	@Autowired MainService mainService;
	@Autowired MainMapper mainMapper;
	
	//profile
	@Value("${spring.profile.active")
	private String profile;
	
	//메인화면
	@GetMapping(Url.MAIN.MAIN)
	public String main() {
		
		return Url.MAIN.MAIN_JSP;
	}
	
	//메인화면 리스트 ajax
	@GetMapping(Url.MAIN.MAIN_LIST_AJAX)
	public String mainListAjax(@RequestParam Map<String, Object> params
								,Pageable pageable
								,Model model
			) {
		
		model.addAttribute("boardList", mainService.selectBoardList(params, pageable, Integer.parseInt(params.get("size").toString())));
		model.addAttribute("resultDataTotal", mainMapper.selectBoardListCnt(params));
		
		return makePageDispatcherUrl(MAIN.MAIN_LIST_AJAX, MAIN._MAIN_AJAX_ROOT_PATH);
	}
	
	
	
	//글쓰기화면
	@GetMapping(Url.MAIN.MAIN_WRITE)
	public String write() {
		return Url.MAIN.MAIN_WRITE_JSP;
	}
	
	//글등록
	@ResponseBody
	@PostMapping(Url.MAIN.MAIN_WRITE)
	public Map<String, Object> writeSubmit(@RequestBody Map<String, Object> params) {
		log.info("params={}", params);
		mainMapper.insertBoard(params);
		
		return params;
	}
	
	//수정화면
	@GetMapping(Url.MAIN.MAIN_UPDATE+"/{boardIdx}")
	public String update(@PathVariable("boardIdx") int boardIdx, Model model) {
		
		log.info("boardIdx={}", boardIdx);
		Map<String, Object> boardInfo = mainMapper.selectBoard(boardIdx);
		
		if(boardInfo != null) {
			model.addAttribute("boardInfo", boardInfo);
			model.addAttribute("boardIdx", boardIdx);
			
			//조회수 업데이트
			mainService.updateViewCount(boardIdx);
		}
		
		else {
			model.addAttribute("boardIdx", "");
		}
		
		return Url.MAIN.MAIN_UPDATE_JSP;
	}
	
	//글수정
	@ResponseBody
	@PostMapping(Url.MAIN.MAIN_UPDATE)
	public Map<String, Object> updateSubmit(@RequestBody Map<String, Object> params) {
		log.info("params={}", params);
		mainMapper.updateBoard(params);
		return params;
	}
	
	/** 게시판 삭제 */
	@ResponseBody
	@PostMapping(Url.MAIN.MAIN_DELETE)
	public List<String> deleteSubmit(@RequestBody List<String> boardIdxArray) {
		
		log.info("boardIdxArray={}", boardIdxArray);
		mainService.deleteBoard(boardIdxArray);
		return boardIdxArray;
	}
	
	//server health check
	@RequestMapping(value= { Constants.HEALTH_CHECK_URL }, produces=MediaType.TEXT_HTML_VALUE)
	   public void healthCheck( HttpServletRequest req, HttpServletResponse res ) throws IOException {

	      String ip = req.getHeader("X-FORWARDED-FOR");
	      if (ip == null) ip = req.getRemoteAddr();

	      PrintWriter pw = res.getWriter();
	      pw.write(" - Active Profile : " + profile + "\n");
	      pw.write(" - Client IP : " + ip);
	      pw.close();
	   }
	
}

 

MainService.java 수정
package com.board.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.board.dao.MainMapper;

import lombok.extern.slf4j.Slf4j;

@Service("mainService")
@Slf4j
public class MainService {

	@Autowired MainMapper mainMapper;
	
	//게시판 조회
	public Page<Map<String, Object>> selectBoardList(Map<String, Object> params, Pageable pageable, int size){
		return new PageImpl<>(mainMapper.selectBoardList(params, pageable, size), pageable, mainMapper.selectBoardListCnt(params));
	}
	
	//게시판 삭제
	public void deleteBoard(List<String> boardIdxArray) {
		for(int i=0; i<boardIdxArray.size(); i++) {
			mainMapper.deleteBoard(boardIdxArray.get(i));
		}
	}
	
	//게시판 조회수 없데이트
	public int updateViewCount(int boardIdx) {
		//조회수 업데이트
		int viewCount = (int) mainMapper.selectBoard(boardIdx).get("viewCount");
		log.info("viewCount={}", viewCount);
		Map<String, Object> params = new HashMap<String, Object>();
		viewCount++;
		params.put("boardIdx", boardIdx);
		params.put("viewCount", viewCount);
		
 		//조회수 업데이트
		return mainMapper.updateViewCount(params);
	}
	
}

 

MainMapper.java 수정
package com.board.dao;


import java.util.List;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import org.apache.ibatis.annotations.Param;

public interface MainMapper {

	//글쓰기 리스트 조회
	public List<Map<String, Object>> selectBoardList(
			 @Param(value = "params") Map<String, Object> params
			,@Param(value = "pageable") Pageable pageable
			,@Param(value = "size") int size);
	
	//글쓰기 리스트 count
	int selectBoardListCnt(@Param(value = "params") Map<String, Object> params);
	
	//글쓰기 등록
	public int insertBoard(Map<String, Object> params);
	
	//글 수정
	public int updateBoard(Map<String, Object> params);
	
	//글쓰기 상세조회
	public Map<String, Object> selectBoard(int boardIdx);
	
	//조회수 업데이트
	public int updateViewCount(Map<String, Object> params);
	
	//겍시판 삭제
	public int deleteBoard(String boardIdx);
	
}

 

MainMapper.xml 수정
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- FAQ SQL Mapper -->
<mapper namespace="com.board.dao.MainMapper">
	
	<!-- 게시판 리스트 조회  -->
	<select id="selectBoardList" resultType="CamelMap">
		SELECT
			 TB.BOARD_IDX
			,TB.BOARD_TITLE
			,TB.BOARD_CONTENT
			,TB.REG_ID
			,TB.VIEW_COUNT
			,TB.USE_YN
			,TB.REG_DATE
			,(SELECT TC.CODE_EXP FROM TB_CODE TC WHERE TC.CODE_NO = '200' AND TC.CODE_NAME = TA.AUTHORITY) AS REG_NAME
		FROM
			 TB_BOARD TB
			,TB_AUTHORITIES TA
		WHERE
			USE_YN = 'Y'
		AND
			TB.REG_ID = TA.USER_ID	
		<if test="pageable != null">
			LIMIT #{pageable.offset}, #{size}
		</if>			
	</select>
	
	<!-- 게시판 count -->
	<select id="selectBoardListCnt" resultType="int">
		SELECT
			COUNT(*)
		FROM
			TB_BOARD
		WHERE
			USE_YN = 'Y'
	</select>
	
	<!-- 게시판 상세 조회 -->
	<select id="selectBoard" resultType="CamelMap">
		SELECT
			 TB.BOARD_IDX
			,TB.BOARD_TITLE
			,TB.BOARD_CONTENT
			,TB.REG_ID
			,TB.VIEW_COUNT
			,TB.USE_YN
			,TB.REG_DATE
			,(SELECT TC.CODE_EXP FROM TB_CODE TC WHERE TC.CODE_NO = '200' AND TC.CODE_NAME = TA.AUTHORITY) AS REG_NAME
		FROM
			TB_BOARD TB
			,TB_AUTHORITIES TA
		WHERE
			USE_YN = 'Y'
		AND
			TB.REG_ID = TA.USER_ID
		AND
			TB.BOARD_IDX = #{boardIdx}		
	</select>
	

	<!-- 게시판 등록 -->
	<insert id="insertBoard">
		INSERT INTO
			TB_BOARD(
				  BOARD_TITLE
				 ,BOARD_CONTENT
				 ,REG_ID
				 ,REG_DATE
			)
			VALUES(
				  #{boardTitle}
				 ,#{boardContent}
				 ,#{userId}
				 ,NOW()
			)
	</insert>
	
	<!-- 게시판 수정 -->
	<update id="updateBoard">
		UPDATE 
			TB_BOARD
		SET
			 BOARD_TITLE = #{boardTitle}
			,BOARD_CONTENT = #{boardContent}
		WHERE
			BOARD_IDX = #{boardIdx}		
	</update>
	
	<!-- 조회수 업데이트 -->
	<update id="updateViewCount">
		UPDATE
			TB_BOARD T1
		SET
			T1.VIEW_COUNT = #{viewCount}
		WHERE
			T1.BOARD_IDX = #{boardIdx}		
	</update>
	
	<!-- 게시판 삭제 -->
	<update id="deleteBoard">
		UPDATE
			TB_BOARD
		SET
			USE_YN = 'N'
		WHERE
			BOARD_IDX = #{boardIdx}		
	</update>
	
	
</mapper>

 

list-js.jsp 수정
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<script>

$(document).ready(function(){
	boardCtrl.init();
});

var boardCtrl = {
	
	init : function(){
		this.bindData();
	},
	
	bindData : function(){
		goPage(0);
	}
}

//리스트 가져오기
function goPage(pageNum){
	var size = "10";
	
	var params = {
		 page : pageNum
		,size : size
	}
	
	util.coGetAjaxPage(
      "/main/ajax/list-view"
      , params
      , 'list-div'
      , function(result){
      }
   );
}

//체크박스 전체 선택 클릭 이벤트
function allChecked(target){
	
	if($(target).is(":checked")){
		//체크박스 전체 체크
		$(".chk").prop("checked", true);
	}
	
	else{
		//체크박스 전체 해제
		$(".chk").prop("checked", false);
	}
}

//자식 체크박스 클릭 이벤트
function cchkClicked(){
	
	//체크박스 전체개수
	var allCount = $("input:checkbox[name=cchk]").length;
	
	//체크된 체크박스 전체개수
	var checkedCount = $("input:checkbox[name=cchk]:checked").length;
	
	//체크박스 전체개수와 체크된 체크박스 전체개수가 같으면 체크박스 전체 체크
	if(allCount == checkedCount){
		$(".chk").prop("checked", true);
	}
	
	//같지않으면 전체 체크박스 해제
	else{
		$("#allCheckBox").prop("checked", false);
	}
}

//게시판 삭제하기
function boardDelete(){
	
	var boardIdxArray = [];
	
	$("input:checkbox[name=cchk]:checked").each(function(){
		boardIdxArray.push($(this).val());
	});
	
	console.log(boardIdxArray);
	
	if(boardIdxArray == ""){
		alert("삭제할 항목을 선택해주세요.");
		return false;
	}
	
	var confirmAlert = confirm('정말로 삭제하시겠습니까?');

	if(confirmAlert){
		
		$.ajax({
	        type : 'POST'
	       ,url : '/board/delete'
	       ,dataType : 'json'
	       ,data : JSON.stringify(boardIdxArray)
	       ,contentType: 'application/json'
	       ,success : function(result) {
				alert("해당글이 정상적으로 삭제되었습니다.");
				goPage(0);
	       },
	       error: function(request, status, error) {
	         
	       }
	   })	
	}
}

</script>

 

list-view.jsp 수정
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ include file="/WEB-INF/template/constants.jsp"%>

<form>
    <table class="table table-hover">
    	<colgroup>
		   <col width="2%" />
		   <col width="5%" />
		   <col width="20%" />
		   <col width="5%" />
		   <col width="5%" />
		   <col width="5%" />
		</colgroup>
        <thead>
            <tr>
            	<th>
            		<label class="checkbox-inline">
						<input type="checkbox" id="allCheckBox" class="chk" onclick="allChecked(this)">
					</label>
            	</th>
                <th>번호</th>
                <th>제목</th>
                <th>작성자</th>
                <th>날짜</th>
                <th>조회수</th>
            </tr>
        </thead>
        <tbody>
        	<c:forEach var="board" items="${boardList.content}" varStatus="vs">
				<tr>
					<td>
						<label class="checkbox-inline">
							<input type="checkbox" class="chk" name="cchk" onclick="cchkClicked()" value="${board.boardIdx}">
						</label>
					<td>${resultDataTotal - (boardList.size * boardList.number) - vs.index}</td>
				    <td><a href='/board/update/${board.boardIdx}'>${board.boardTitle}</a></td>
				    <td>${board.regName}</td>
				    <td>
				    	<fmt:parseDate value="${board.regDate}" var="regDate" pattern="yyyy-MM-dd HH:mm:ss.s"/>
						<fmt:formatDate value="${board.regDate}" pattern="yyyy-MM-dd"/>
					</td>
				    <td>${board.viewCount}</td>
				</tr>
			</c:forEach>
			
			<c:if test="${resultDataTotal == 0}">
				<tr>
					<center><td colspan="6" style="text-align: center;">등록된 게시판 리스트가 없습니다.</td></center>
				</tr>
			</c:if>
				
        </tbody>
    </table>
   	
   	<!-- ADMIN 권한일경우에만 글쓰기 권한있음 -->
   	<c:if test="${sessUserInfo.authority == 'ADMIN'}">
		<div class="text-right">            
			<a href='javascript:boardDelete();' class="btn btn-danger">글삭제</a>      
            <a href='/board/write' class="btn btn-primary">글쓰기</a>            
		</div>
    </c:if>
   	 
    <div class="text-center">
    	<c:if test="${resultDataTotal != 0}">
         <ul class="pagination">
            <paginator:print goPageScript="goPage" curPage="${boardList.number}" totPages="${boardList.totalPages}"/>
         </ul>
      </c:if>
    
    	<!--
    	<ul class="pagination">
    		<li><a href="#">prev</a></li>
    		<li><a href="#">1</a></li>
    		<li><a href="#">2</a></li>
    		<li><a href="#">3</a></li>
    		<li><a href="#">4</a></li>
    		<li><a href="#">5</a></li>
    		<li><a href="#">next</a></li>
    	</ul>
    	-->
    </div>	
</form>

 

update.jsp 수정
<%@ page language="java" session="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/WEB-INF/template/constants.jsp"%>

<body>
	<article>
		<div class="container" role="main">
			<h2>게시판 상세</h2>
			<form name="form" id="form" role="form" method="post" action="${pageContext.request.contextPath}/board/saveBoard">
				<div class="mb-3">
					<label for="title">제목</label>
					<input type="text" class="form-control" id="boardTitle" name="boardTitle" placeholder="제목을 입력해 주세요" value="${boardInfo.boardTitle}" <c:if test="${sessUserInfo.authority != 'ADMIN'}">readonly</c:if>>
					<input type="hidden" id="boardIdx" value="${boardIdx}" />
				</div>
			
				<div class="mb-3">
					<label for="reg_id">작성자</label>
					<input type="text" class="form-control" id="regId" name="regId"  value="${boardInfo.regName}" readonly>
				</div>

				
				<div class="mb-3">
					<label for="content">내용</label>
					<textarea class="form-control" rows="5" id="boardContent" name="boardContent" placeholder="내용을 입력해 주세요" <c:if test="${sessUserInfo.authority != 'ADMIN'}">readonly</c:if>>${boardInfo.boardContent}</textarea>
				</div>	
			</form>
			
			<br>
			<c:if test="${sessUserInfo.authority == 'ADMIN'}">
				<div>
					<button onclick="writeSubmit()" type="button" class="btn btn-sm btn-primary" id="btnSave">수정</button>
					<button onclick="boardDelete()" type="button" class="btn btn-sm btn-danger" >삭제</button>
					<button onclick="location.href='/'" type="button" class="btn btn-sm btn-primary" id="btnList">목록</button>
				</div>
			</c:if>
		</div>
	</article>
</body>

 

update-js.jsp 수정
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<script>
	
	$(document).ready(function(){
		
		//게시물번호가 없을경우
		if("${boardIdx}" == ""){
			alert("해당 게시물은 없는 번호입니다.");
			location.href="/";
		}
		
	});
	
	//수정 버튼
	function writeSubmit(){
		
		var params = {
			 boardTitle : $.trim($("#boardTitle").val())
			,boardContent : $.trim($("#boardContent").val())
			,userId : "${sessUserInfo.userId}"
			,boardIdx : $("#boardIdx").val()
		}
		
		console.log(params);
		
		if(params.boardTitle == ""){
			alert("제목을 입력해주세요.");
			return false;
		}
		
		else if(params.boardContent == ""){
			alert("내용을 입력해주세요.");
			return false;
		} 
		
		$.ajax({
	         type : 'POST'
	        ,url : '/board/update'
	        ,dataType : 'json'
	        ,data : JSON.stringify(params) 
	        ,contentType: 'application/json'
	        ,success : function(result) {
				alert("해당글이 정상적으로 수정되었습니다.");
				location.href="/";
	        },
	        error: function(request, status, error) {
	          
	        }
	    }) 
	}

	//게시판 삭제하기
	function boardDelete(){
		
		var boardIdxArray = [];
		
		boardIdxArray.push("${boardIdx}");
		
		console.log(boardIdxArray);
		
		if(boardIdxArray == ""){
			alert("삭제할 항목을 선택해주세요.");
			return false;
		}
		
		var confirmAlert = confirm('정말로 삭제하시겠습니까?');

		if(confirmAlert){
			
			$.ajax({
		        type : 'POST'
		       ,url : '/board/delete'
		       ,dataType : 'json'
		       ,data : JSON.stringify(boardIdxArray)
		       ,contentType: 'application/json'
		       ,success : function(result) {
					alert("해당글이 정상적으로 삭제되었습니다.");
					location.href="/";
		       },
		       error: function(request, status, error) {
		         
		       }
		   })	
		}
	}
	
</script>

 

리스트 화면

 

전체체크박스 체크시

 

체크박스 하나라도 풀렸을경우

 

체크박스 삭제

-> 삭제시 flag를 N으로 업데이트해서 논리삭제 처리함

 

수정화면

 

다음 포스팅에서는 멀티파일 업로드 기능을 개발 및 적용을 해보겠습니다. 감사합니다.

복사했습니다!