728x90
list.jsp에 추가
카테고리 관련 데이터를 취득
list.jsp 변경
T_SQL.XML에 추가
AND T.CATE_NO = #{cateNo} 등등 cata관련 추가
<?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">
<mapper namespace="T">
<select id="getTCnt" resultType="Integer" parameterType="hashmap">
SELECT COUNT(*) AS CNT
FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
AND M.DEL = 1
WHERE T.DEL = 1
AND T.CATE_NO = #{cateNo}
<if test="searchTxt != null and searchTxt !=''">
<choose>
<when test="searchGbn eq 0">
AND T.TITLE LIKE '%' || #{searchTxt} || '%'
</when>
<when test="searchGbn eq 1">
AND M.MEM_NM LIKE '%' || #{searchTxt} || '%'
</when>
</choose>
</if>
</select>
<select id="getTList" resultType="hashmap" parameterType="hashmap">
SELECT T.NO, T.TITLE, T.MEM_NM, T.HIT, T.DT, T.ATT
FROM(
SELECT T.NO, T.TITLE, M.MEM_NM, T.HIT,
CASE WHEN TO_CHAR(DT,'YY.MM.DD') = TO_CHAR(SYSDATE, 'YY.MM.DD')
THEN TO_CHAR(DT, 'HH24:MI')
ELSE TO_CHAR(DT, 'YY.MM.DD')
END AS DT, ATT,
ROW_NUMBER() OVER(ORDER BY T.NO DESC) AS RNUM
FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
AND M.DEL = 1
WHERE T.DEL = 1
AND T.CATE_NO = #{cateNo}
<if test="searchTxt != null and searchTxt !=''">
<choose>
<when test="searchGbn eq 0">
AND T.TITLE LIKE '%' || #{searchTxt} || '%'
</when>
<when test="searchGbn eq 1">
AND M.MEM_NM LIKE '%' || #{searchTxt} || '%'
</when>
</choose>
</if>) T
WHERE T.RNUM BETWEEN #{start} AND #{end}
</select>
<insert id="insertT" parameterType="hashmap">
INSERT INTO TBOARD(NO, TITLE, MEM_NO, CON, ATT, CATE_NO)
VALUES (TBOARD_SEQ.NEXTVAL, #{title} , #{memNo}, #{con}, #{att}, #{cateNo})
</insert>
<select id="getT" parameterType="hashmap" resultType="hashmap">
SELECT T.NO, T.TITLE, M.MEM_NO, M.MEM_NM, T.CON, T.HIT,
TO_CHAR(T.DT, 'YYYY-MM-DD') AS DT, T.ATT
FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
AND M.DEL = 1
WHERE T.DEL = 1
AND T.NO = #{no}
</select>
<update id="updateTHit" parameterType="hashmap">
UPDATE TBOARD SET HIT = HIT + 1
WHERE NO = #{no}
</update>
<update id="deleteT" parameterType="hashmap">
UPDATE TBOARD SET DEL = 0
WHERE NO = #{no}
</update>
<update id="updateT" parameterType="hashmap">
UPDATE TBOARD SET TITLE = #{title},
CON = #{con},
ATT = #{att}
WHERE NO = #{no}
</update>
</mapper>
코드형 게시판
동시에 여러개의 테이블을 하나의 게시판으로
블로그는 카테고리 대신 내 아이디를 항상 조건으로!
다음주, 스케줄링 관련
주기적으로 도는 프로그램
특정 요일에 도는 프로그램
쓰는건 간단, 이해하는게 어렵
Restful Controller -> jsp관련
T에 있는 화면 수정 T를 카테고리 자유게시판으로
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
#searchTxt{
width: 160px;
height: 30px;
padding: 0px 2px;
text-indent: 5px;
vertical-align: middle;
border: 1px solid #d7d7d7;
outline-color: #70adf9;
box-sizing: border-box;
}
.search_area{
width: 800px;
text-align: right;
margin: 0 auto;
}
.board_area{
width: 800px;
margin: 0 auto;
}
.att {
display: inline-block;
vertical-align: top;
width: 18px;
height: 18px;
background-image: url('resources/images/attFile.png');
background-size: cover;
}
#cateNo {
min-width: 100px;
height: 30px;
vertical-align: middle;
boder: 1px soild #d7d7d7;
float: left
}
</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
src="resources/script/common/popup.js"></script>
<script type="text/javascript">
$(document).ready(function () {
if("${params.searchGbn}" != ""){
$("#searchGbn").val("${param.searchGbn}");
} else {
$("#oldGbn").val("0");
}
// 카테고리 설정
if("${param.cateNo}" != ""){
$("#cateNo").val("${param.cateNo}");
}
// 카테고리 변경시
$("#cateNo").on("change", function () {
// 검색 및 페이징 초기화
$("#page").val("1");
$("#searchGbn").val("0");
$("#searchTxt").val("");
$("#oldGbn").val("0");
$("#oldTxt").val("");
//목록 조회
reloadList();
})
//목록 조회
reloadList();
//검색버튼
$("#searchBtn").on("click", function () {
$("#page").val("1");
// 이동을 안하다보니 문제가 기존검색값 셋팅을 안해줌
// 그래서 신규 상태 적용
$("#oldGbn").val($("#searchGbn").val());
$("#oldTxt").val($("#searchTxt").val());
// 데이터만 가져와서 다시 그려줌, 화면 이동 없음
reloadList();
});
//페이징 버튼
$(".paging_area").on("click", "span", function () {
// 기존 검색상태 유지
$("#searchGbn").val($("#oldGbn").val());
$("#searchTxt").val($("#oldTxt").val());
$("#page").val($(this).attr("page"));
reloadList();
})
// 등록버튼
$("#insertBtn").on("click", function () {
// 기존 검색상태 유지
$("#searchGbn").val($("#oldGbn").val());
$("#searchTxt").val($("#oldTxt").val());
$("#actionForm").attr("action", "ATInsert");
$("#actionForm").submit();
})
$("tbody").on("click", "tr", function () {
$("#no").val($(this).attr("no"));
$("#searchGbn").val($("#oldGbn").val());
$("#searchTxt").val($("#oldTxt").val());
$("#actionForm").attr("action", "ATDetail");
$("#actionForm").submit();
})
});
// 목록 조회 호출, ajax불러오기
function reloadList() {
var params = $("#actionForm").serialize();
$.ajax({
url : "ATListAjax", //경로
type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
dataType: "json", // 데이터 형태
data: params, // 보낼데이터
success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
console.log(res); // 콘솔에 pd랑 list 값이 보임
drawList(res.list);
drawPaging(res.pd);
},
error : function(request, status, error) { // 실패했을 때 함수실행
console.log(request.responseText); // 실패 상세 태역
}
});
}
function drawList(list) {
var html = "";
// list에는 map이 들어있으니까 하나씩 꺼내오겠다
for(var data of list){
console.log(typeof(data.ATT) !="undefined");
html += "<tr no=\"" + data.NO + "\">";
html += "<td>" + data.NO + "</td>";
html += "<td>";
html += data.TITLE;
if(typeof(data.ATT) !="undefined"){ // 첨부파일이 있다면
html += "<span class=\"att\"></span>";
}
html += "</td>";
html += "<td>" + data.MEM_NM + "</td>";
html += "<td>" + data.DT + "</td>";
html += "<td>" + data.HIT + "</td>";
html += "</tr>";
}
$("tbody").html(html);
}
function drawPaging(pd) {
var html = "";
html += "<span class=\"page_btn page_first\" page=\"1\">처음</span>";
// 이전
if($("#page").val() == "1"){
html += "<span class=\"page_btn page_prev\" page=\"1\">이전</span>";
} else{
// 문자열을 숫자로 바꾸기위해 *1
html += "<span class=\"page_btn page_prev\" page=\"" + ($("#page").val() *1 - 1) + "\">이전</span>";
}
for(var i = pd.startP; i <= pd.endP; i++){
if($("#page").val() * 1 == i){ // 현재 페이지
html += "<span class=\"page_btn_on\" page=\"" + i + "\">" + i + "</span>";
} else { // 다른 페이지
html += "<span class=\"page_btn\" page=\"" + i + "\">" + i + "</span>";
}
}
if($("#page").val() *1 == pd.endP){ // 현재페이지가 마지막 페이지라면
html += "<span class=\"page_btn page_next\" page=\"" +pd.maxP+ "\">다음</span>";
} else {
html += "<span class=\"page_btn page_next\" page=\"" + ($("#page").val() *1 + 1) + "\">다음</span>";
}
html += "<span class=\"page_btn page_last\" page=\"" +pd.maxP+ "\">마지막</span>";
$(".paging_area").html(html);
}
</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<hr/>
<!-- 페이징 때 기존 검색 내용 유지용 -->
<input type="hidden" id="oldGbn" value="${param.searchGbn}"/>
<input type="hidden" id="oldTxt" value="${param.searchTxt}"/>
<!-- 데이터 후 처리해서 로딩이 빨라 -->
<div class="search_area">
<!-- method="post"는 나중에 쓸 예정, no 보낼때 -->
<form action="#" id="actionForm" method="post">
<select name="cateNo" id="cateNo">
<c:forEach var="data" items="${cate}">
<option value="${data.CATE_NO}">${data.CATE_NM}</option>
</c:forEach>
</select>
<input type="hidden" name="no" id="no" />
<input type="hidden" name="page" id="page" value="${page}" />
<select name="searchGbn" id="searchGbn">
<option value="0">제목</option>
<option value="1">작성자</option>
</select>
<input type="text" name="searchTxt" id="searchTxt" value="${param.searchTxt}" />
<div class="cmn_btn_ml" id="searchBtn">검색</div>
<c:if test="${!empty sMemNo}">
<div class="cmn_btn_ml" id="insertBtn">등록</div>
</c:if>
</form>
</div>
<div class="board_area">
<table class="board_table">
<colgroup>
<col width="100" />
<col width="400" />
<col width="100" />
<col width="100" />
<col width="100" />
</colgroup>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
</thead>
<tbody></tbody>
</table>
<div class="paging_area"></div>
</div>
</body>
</html>
insert.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.wrap{
width: 800px;
margin: 0 auto;
}
</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
src="resources/script/jquery/jquery.form.js"></script>
<script type="text/javascript"
src="resources/script/common/popup.js"></script>
<!-- CKEditor -->
<!-- 제이쿼리 뒤에 나와야함, 제이쿼리 기반으로 동작하기 때문에 -->
<script type="text/javascript" src="resources/script/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// 에디터 연결
// CKEDITOR.replace(아이디, 옵션)
CKEDITOR.replace("con", {
resize_enabled: false, // resize_enabled : 크기조절기능 활용여부
language : "ko", // 사용언어
enterMode: "2", // 엔터키처리방법. 2번이면 <br/>
width : "100%", // 숫자일경우 px, 문자열일경우 css크기
height : 400
});
$("#listBtn").on("click", function () {
$("#backForm").submit();
});
$("#insertBtn").on("click", function () {
// CKEditor의 값 취득
// CKEDITOR.instances[아이디] : CKEditor중 아이디가 같은 것을 찾겠다.
//.getData() : 작성중인 내용을 취득하겠다.
$("#con").val(CKEDITOR.instances['con'].getData());
if($.trim($("#title").val()) == ""){
makeAlert("알림","제목 입력하세요." , function () {
$("#title").focus();
})
} else if($.trim($("#con").val()) == ""){
makeAlert("알림","내용을 입력하세요." , function () {
$("#con").focus();
})
} else {
// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
// 폼 객체 취득
var form = $("#actionForm");
// ajaxForm 적용
form.ajaxForm({
success: function (res) { // 데이터 주고 받기 성공시
if(res.result == "SUCCESS"){ // 파일 전송 성공
// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
if(res.fileName.length > 0){
$("#att").val(res.fileName[0]); // 올라간 파일명 보관
}
// 3번 단계 글저장 시작, 기존테이터
var params = $("#actionForm").serialize();
$.ajax({
url : "ATAction/insert", //restful api라는게 여기서 시작한다고?
type : "POST",
dataType: "json",
data: params,
success : function(res) {
switch(res.msg){
case "success" :
// 카테고리를 유지하고 나머지 정보 초기화
$("#page").val("1");
$("#searchGbn").val("0");
$("#searchTxt").val("");
$("#backForm").submit();
break;
case "fail" :
makeAlert("알림" , "등록에 실패하였습니다.");
break;
case "error" :
makeAlert("알림" , "등록 중 문제가 발생하였습니다.");
break;
}
},
error : function(request, status, error) {
console.log(request.responseText);
}
}); // 글저장 끝
} else { // 문제발생
makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
}
},
error: function () { // 에러시
makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
}
}); // ajaxForm 설정 끝
// ajaxForm 실행
form.submit();
}
});
});
</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="ATList" id="backForm" method="post">
<input type="hidden" name="page" id="page" value="${param.page}" />
<input type="hidden" name="searchGbn" id="searchGbn" value="${param.searchGbn}"/>
<input type="hidden" name="searchTxt" id="searchTxt" value="${param.searchTxt}"/>
<!-- 전화면에서 넘어온 카테고리 번호 -->
<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</form>
<!-- ajax쓰기 때문에 gbn 지움 -->
<div class="wrap">
<form action="fileUploadAjax" id="actionForm" method="post" enctype="multipart/form-data">
<input type="hidden" name="att" id="att" /> <!-- 실 저장된 파일명 보관용 -->
<table class="board_detail_table">
<tr>
<th>카테고리</th>
<td>${cateNm}<input type="hidden" name="cateNo"value="${param.cateNo}"/></td>
</tr>
<tr>
<th>제목</th>
<td><input type="text" name="title" id="title" /></td>
</tr>
<tr>
<th>작성자</th>
<td>${sMemNm}<input type="hidden" name="memNo" value="${sMemNo}" /><br/></td>
</tr>
<tr>
<th colspan="2">내용</th>
</tr>
<tr>
<th colspan="2"><textarea rows="10" cols="30" name="con" id="con"></textarea></th>
</tr>
<tr>
<th>첨부파일</th>
<td><input type="file" name="attFile" /></td>
</tr>
</table>
</form>
<div class="cmn_btn_ml float_right_btn" id="listBtn">목록</div>
<div class="cmn_btn_ml float_right_btn" id="insertBtn">등록</div>
</div>
</body>
</html>
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- jsl의 functions : el tag 추가옵션 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상세보기</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.wrap{
width: 800px;
margin: 0 auto;
}
.con{
text-align: left;
min-height: 400px;
}
</style>
<script type="text/javascript"
src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
src="resources/script/common/popup.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#listBtn").on("click", function() {
$("#actionForm").attr("action","ATList");
$("#actionForm").submit();
});
// ajax사용 예정
$("#deleteBtn").on("click", function () {
makePopup({
title : "알림",
contents : "삭제하시겠습니까?",
// draggable : true,
buttons : [{
name : "삭제",
func:function() {
var params = $("#actionForm").serialize();
$.ajax({
url : "ATAction/delete", //restful api라는게 여기서 시작한다고?
type : "POST",
dataType: "json",
data: params,
success : function(res) {
switch(res.msg){
case "success" :
// 카테고리를 유지하고 나머지 정보 초기화
$("#page").val("1");
$("#searchGbn").val("0");
$("#searchTxt").val("");
$("#actionForm").attr("action","ATList");
$("#actionForm").submit();
break;
case "fail" :
makeAlert("알림" , "삭제에 실패하였습니다.");
break;
case "error" :
makeAlert("알림" , "삭제 중 문제가 발생하였습니다.");
break;
}
},
error : function(request, status, error) {
console.log(request.responseText);
}
});
}
}, {
name : "취소"
}]
});
});
$("#updateBtn").on("click", function () {
$("#actionForm").attr("action","ATUpdate");
$("#actionForm").submit();
});
});
</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="#" id="actionForm" method="post">
<input type="hidden" name="gbn" value="d"> <!-- selRes는 gbn을 받게 되어있어서 값을 추가해줘야함, 이 화면에서는 없어도 됨 -->
<input type="hidden" name="no" value="${data.NO}">
<input type="hidden" name="page" id="page" value="${param.page}" /> <!-- 전 화면에서 넘어온 페이지 정보 -->
<!-- 전 화면에서 넘어온 검색 정보 -->
<input type="hidden" name="searchGbn" id="searchGbn" value="${param.searchGbn}"/>
<input type="hidden" name="searchTxt" id="searchTxt" value="${param.searchTxt}"/>
<!-- 전화면에서 넘어온 카테고리 번호 -->
<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</form>
<div class="wrap">
<table class="board_detail_table">
<tr>
<th>카테고리</th>
<td>${cateNm}</td>
</tr>
<tr>
<th>번호</th>
<td>${data.NO}</td>
</tr>
<tr>
<th>제목</th>
<td>${data.TITLE}</td>
</tr>
<tr>
<th>작성자</th>
<td>${data.MEM_NM}</td>
</tr>
<tr>
<th>조회수</th>
<td> ${data.HIT}</td>
</tr>
<tr>
<th>작성일</th>
<td> ${data.DT}</td>
</tr>
<tr>
<th colspan="2">내용</th>
</tr>
<tr>
<td class="con" colspan="2">${data.CON}</td>
</tr>
<c:if test="${!empty data.ATT}">
<!-- fn:length(대상) : 대상 문자열의 길이나 배열, 리스트의 크기를 가져온다 -->
<c:set var="fileLength" value="${fn:length(data.ATT)}"></c:set>
<!-- fn:substring(값, 숫자1, 숫자2) : 값을 숫자1이상부터, 숫자2미만까지, 인덱스 기준으로 자른다. -->
<c:set var="fileName" value="${fn:substring(data.ATT, 20, fileLength)}"></c:set>
<tr>
<th>첨부파일</th>
<!-- download 없으면 이미지를 브라우저에 띄움, 파일을 안 받고 -->
<!-- download="${fileName}" 옵션을 줘야 다운받을때도 파일명으로 받아짐 -->
<td><a href="resouces/upload/${data.ATT}" download="${fileName}">${fileName}</a></td>
</tr>
</c:if>
</table>
<div class="cmn_btn_ml float_right_btn" id="listBtn">목록</div>
<c:if test="${sMemNo eq data.MEM_NO}">
<div class="cmn_btn_ml float_right_btn" id="deleteBtn">삭제</div>
<div class="cmn_btn_ml float_right_btn" id="updateBtn">수정</div>
</c:if>
</div>
</body>
update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- jsl의 functions : el tag 추가옵션 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글수정</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.wrap{
width: 800px;
margin: 0 auto;
}
.att {
display: none;
}
</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
src="resources/script/jquery/jquery.form.js"></script>
<script type="text/javascript"
src="resources/script/common/popup.js"></script>
<!-- CKEditor -->
<!-- 제이쿼리 뒤에 나와야함, 제이쿼리 기반으로 동작하기 때문에 -->
<script type="text/javascript" src="resources/script/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// 에디터 연결
// CKEDITOR.replace(아이디, 옵션)
CKEDITOR.replace("con", {
resize_enabled: false, // resize_enabled : 크기조절기능 활용여부
language : "ko", // 사용언어
enterMode: "2", // 엔터키처리방법. 2번이면 <br/>
width : "100%", // 숫자일경우 px, 문자열일경우 css크기
height : 400
});
$("#cancelBtn").on("click", function () {
$("#backForm").submit();
});
// 첨부파일 파일삭제 버튼 클릭시
$("#fileDelBtn").on("click", function () {
// 기존 파일 내역 영역 제거
$(".attOld").remove();
// 기존 값 제거
$("#att").val("");
// 파일 선택 영역 제공
$(".att").show();
});
$("#updateBtn").on("click", function () {
// CKEditor의 값 취득
// CKEDITOR.instances[아이디] : CKEditor중 아이디가 같은 것을 찾겠다.
//.getData() : 작성중인 내용을 취득하겠다.
$("#con").val(CKEDITOR.instances['con'].getData());
if($.trim($("#title").val()) == ""){
makeAlert("알림","제목 입력하세요." , function () {
$("#title").focus();
})
} else if($.trim($("#con").val()) == ""){
makeAlert("알림","내용을 입력하세요." , function () {
$("#con").focus();
})
} else {
// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
// 폼 객체 취득
var form = $("#actionForm");
// ajaxForm 적용
form.ajaxForm({
success: function (res) { // 데이터 주고 받기 성공시
if(res.result == "SUCCESS"){ // 파일 전송 성공
// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
if(res.fileName.length > 0){
$("#att").val(res.fileName[0]); // 올라간 파일명 보관
}
// 3번 단계 글저장 시작, 기존테이터
var params = $("#actionForm").serialize();
$.ajax({
url : "ATAction/update", //restful api라는게 여기서 시작한다고?
type : "POST",
dataType: "json",
data: params,
success : function(res) {
switch(res.msg){
case "success" :
$('#backForm').submit();
break;
case "fail" :
makeAlert("알림" , "등록에 실패하였습니다.");
break;
case "error" :
makeAlert("알림" , "등록 중 문제가 발생하였습니다.");
break;
}
},
error : function(request, status, error) {
console.log(request.responseText);
}
}); // 글저장 끝
} else { // 문제발생
makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
}
},
error: function () { // 에러시
makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
}
}); // ajaxForm 설정 끝
// ajaxForm 실행
form.submit();
}
});
});
</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="ATDetail" id="backForm" method="post">
<input type="hidden" name="no" value="${data.NO}" />
<input type="hidden" name="page" value="${param.page}" />
<input type="hidden" name="searchGbn" value="${param.searchGbn}"/>
<input type="hidden" name="searchTxt" value="${param.searchTxt}"/>
<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</form>
<!-- ajax쓰기 때문에 gbn 지움 -->
<div class="wrap">
<form action="fileUploadAjax" id="actionForm" method="post" enctype="multipart/form-data">
<input type="hidden" name="no" value="${data.NO}" />
<!-- 전화면에서 넘어온 카테고리 번호 -->
<input type="hidden" name="cateNo"value="${param.cateNo}"/>
<table class="board_detail_table">
<tr>
<th>카테고리</th>
<td>${cateNm}</td>
</tr>
<tr>
<th>번호</th>
<td>${data.NO}</td>
</tr>
<tr>
<th>제목</th>
<td><input type="text" name="title" id="title" value="${data.TITLE}"/></td>
</tr>
<tr>
<th>작성자</th>
<td>${sMemNm}</td>
</tr>
<tr>
<th colspan="2">내용</th>
</tr>
<tr>
<th colspan="2"><textarea rows="10" cols="30" name="con" id="con">${data.CON}</textarea></th>
</tr>
<tr>
<th>첨부파일</th>
<c:choose>
<c:when test="${empty data.ATT}">
<!-- 파일이 없을때 -->
<td>
<input type="file" name="attFile" />
<input type="hidden" name="att" id="att"/>
</td>
</c:when>
<c:otherwise>
<!-- 파일이 있을때 -->
<td>
<span class="attOld"> <!-- 기존 파일 -->
<!-- fn:length(대상) : 대상 문자열의 길이나 배열, 리스트의 크기를 가져온다 -->
<c:set var="fileLength" value="${fn:length(data.ATT)}"></c:set>
<!-- fn:substring(값, 숫자1, 숫자2) : 값을 숫자1이상부터, 숫자2미만까지, 인덱스 기준으로 자른다. -->
<c:set var="fileName" value="${fn:substring(data.ATT, 20, fileLength)}"></c:set>
${fileName}
<div class="cmn_btn_ml float_right_btn" id="fileDelBtn">파일삭제</div>
</span>
<span class="att"> <!-- 기존 파일 삭제 후 새 파일 용도 -->
<input type="file" name="attFile" />
<input type="hidden" name="att" id="att" value="${data.ATT}"/>
</span>
</td>
</c:otherwise>
</c:choose>
</tr>
</table>
</form>
<div class="cmn_btn_ml float_right_btn" id="cancelBtn">취소</div>
<div class="cmn_btn_ml float_right_btn" id="updateBtn">수정</div>
</div>
</body>
</html>
ATController.java
package com.spring.sample.web.testa.Controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.sample.common.service.IPagingService;
import com.spring.sample.web.testa.dao.IACDao;
@Controller
public class ATController {
@Autowired
public IACDao iACDao;
@Autowired
public IPagingService ips;
@RequestMapping(value = "/ATList")
public ModelAndView ATList(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
// 비동기가 되면 일단 아무것도 처음에 셋팅 X,
// 페이지만 셋팅
int page = 1;
if (params.get("page") != null && params.get("page") != "") {
page = Integer.parseInt(params.get("page"));
}
// 카테고리 목록 취득
List<HashMap<String, String>> cate = iACDao.getList("cob.getCateAllList");
mav.addObject("page", page);
mav.addObject("cate", cate);
mav.setViewName("testa/T/list");
return mav;
}
@RequestMapping(value = "/ATListAjax", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
@ResponseBody
public String ATListAjax(@RequestParam HashMap<String, String> params) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> model = new HashMap<String, Object>();
// 페이지 받아오게 되어있음
int cnt = iACDao.getInt("T.getTCnt", params);
HashMap<String, Integer> pd = ips.getPagingData(Integer.parseInt(params.get("page")), cnt, 10, 5);
params.put("start", Integer.toString(pd.get("start")));
params.put("end", Integer.toString(pd.get("end")));
List<HashMap<String, String>> list = iACDao.getList("T.getTList", params);
model.put("list", list);
model.put("pd", pd);
return mapper.writeValueAsString(model);
}
@RequestMapping(value = "/ATInsert")
public ModelAndView aTInsert(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
String cateNm = iACDao.getString("cob.getCate", params);
mav.addObject("cateNm", cateNm);
mav.setViewName("testa/T/insert");
return mav;
}
@RequestMapping(value = "/ATAction/{gbn}", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
@ResponseBody
public String ATAction(@PathVariable String gbn, @RequestParam HashMap<String, String> params) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> model = new HashMap<String, Object>();
int cnt = 0;
try {
switch (gbn) {
case "insert":
cnt = iACDao.insert("T.insertT", params);
break;
case "update":
cnt = iACDao.update("T.updateT", params);
break;
case "delete":
cnt = iACDao.update("T.deleteT", params);
break;
}
if (cnt > 0) {
model.put("msg", "success");
} else {
model.put("msg", "fail");
}
} catch (Exception e) {
e.printStackTrace();
model.put("msg", "error");
}
return mapper.writeValueAsString(model);
}
// 가져오고 변경되는게 없기 때문에 비동기 처리로 안되도 됨
@RequestMapping(value = "/ATDetail")
public ModelAndView aTDetail(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
// 글번호 안 넘어왔을때 처리
if (params.get("no") != null && params.get("no") != "") {
// 조회수
iACDao.update("T.updateTHit", params);
HashMap<String, String> data = iACDao.getMap("T.getT", params);
String cateNm = iACDao.getString("cob.getCate", params);
mav.addObject("cateNm", cateNm);
mav.addObject("data", data);
mav.setViewName("testa/T/detail");
} else {
mav.setViewName("redirect:ATList");
}
return mav;
}
@RequestMapping(value = "/ATUpdate")
public ModelAndView aTUpdate(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
// 글번호 안 넘어왔을때 처리
if (params.get("no") != null && params.get("no") != "") {
HashMap<String, String> data = iACDao.getMap("T.getT", params);
String cateNm = iACDao.getString("cob.getCate", params);
mav.addObject("cateNm", cateNm);
mav.addObject("data", data);
mav.setViewName("testa/T/update");
} else {
mav.setViewName("redirect:ATList");
}
return mav;
}
}
Cate_SQL.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">
<mapper namespace="cob">
<insert id="insertOb" parameterType="hashmap">
INSERT INTO CATE(CATE_NO, CATE_NM) VALUES (CATE_SEQ.NEXTVAL, #{cateNm})
</insert>
<update id="updateOb" parameterType="hashmap">
UPDATE CATE SET CATE_NM = #{cateNm}
WHERE CATE_NO = #{no}
</update>
<update id="deleteOb" parameterType="hashmap">
UPDATE CATE SET DEL = 0
WHERE CATE_NO = #{no}
</update>
<select id="getObCnt" parameterType="hashmap" resultType="Integer">
SELECT COUNT(*) AS CNT
FROM CATE
WHERE DEL = 1
<if test="searchText != null and searchText != ''">
<choose>
<when test="searchGbn eq 0">
AND CATE_NO = #{searchText}
</when>
<when test="searchGbn eq 1">
AND CATE_NM LIKE '%' || #{searchText} || '%'
</when>
</choose>
</if>
</select>
<select id="getObList" parameterType="hashmap" resultType="hashmap">
SELECT S.CATE_NO, S.CATE_NM
FROM(SELECT CATE_NO, CATE_NM,
ROW_NUMBER() OVER(ORDER BY CATE_NO DESC, CATE_NM DESC) AS RNK
FROM CATE
WHERE DEL = 1
<if test="searchText != null and searchText != ''">
<choose>
<when test="searchGbn eq 0">
AND CATE_NO = #{searchText}
</when>
<when test="searchGbn eq 1">
AND CATE_NM LIKE '%' || #{searchText} || '%'
</when>
</choose>
</if>
) S
WHERE S.RNK BETWEEN #{start} AND #{end}
</select>
<select id="getCateAllList" resultType="hashmap">
SELECT CATE_NO, CATE_NM
FROM CATE
WHERE DEL = 1
</select>
<!-- 이름 취득용 -->
<select id="getCate" parameterType="hashmap" resultType="String">
SELECT CATE_NM
FROM CATE
WHERE DEL = 1
AND CATE_NO = #{cateNo}
</select>
</mapper>
총 수정한곳 7군데
728x90