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으로 업데이트해서 논리삭제 처리함
수정화면 |
다음 포스팅에서는 멀티파일 업로드 기능을 개발 및 적용을 해보겠습니다. 감사합니다.
'스프링' 카테고리의 다른 글
[SPRING JPA] 쿼리 파라미터 로그 남기기 p6spy (0) | 2021.09.07 |
---|---|
[Spring Boot] 7. 게시판 멀티파일 업로드, 파일 다운로드(Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (1) | 2021.08.15 |
[Spring Boot] 5. logback 설정 (Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (0) | 2021.08.12 |
[Spring] sts4에서 jsp 사용하기 (0) | 2021.08.12 |
[Spring Boot] 4. 게시판 CRUD, 페이징처리 (Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (0) | 2021.08.07 |