회원 테이블 설계
create table member(
id varchar(20) not null,
pw varchar(50) not null,
name varchar(10) not null,
primary key(id)
);
insert into member values('smhrd4','smhrd4','퓨어맨');
create table board2(
idx int not null auto_increment,
title varchar(100) not null,
writer varchar(10) not null,
indate datetime default now(),
contents varchar(2000) not null,
id varchar(20) not null,
cnt int,
primary key(idx)
);
basic.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!-- 프로젝트의 contextpath값을 동적으로 가져오는 방법 -->
<c:set var= "cpath" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<!-- bootstrap 사용하기 위해 필요한 라이브러리 3개! -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div class = "container">
<h2>jQuery+ajax+Session관리</h2>
<div class="panel panel-default">
<div class="panel-heading">
<c:if test="${empty mvo}">
<form class="form-inline" action="${cpath}/login.do">
<div class="form-group">
<label for="id">아이디:</label>
<input type="text" class="form-control" id="id" name="id">
</div>
<div class="form-group">
<label for="pw">비밀번호:</label>
<input type="password" class="form-control" id="pw" name="pw">
</div>
<button type="submit" class="btn btn-default">로그인</button>
</form>
</c:if>
<c:if test="${!empty mvo}">
<label>${mvo.name}님 환영합니다!</label>
<button onclick='location.href="${cpath}/logout.do"' class = 'btn btn-warning btn-sm'>로그아웃</button>
</c:if>
</div>
<div class="panel-body">
<table class = "table table-bordered table-hover">
<tr class = "heading">
<td>번호</td>
<td>제목</td>
<td>작성자</td>
<td>작성일</td>
<td>삭제</td>
</tr>
<c:if test="${!empty mvo}">
<tr>
<td colspan = "5">
<button onclick="goInsert()" class = "btn btn-primary btn-sm">글쓰기</button>
</td>
</tr>
</c:if>
</table>
<div id="insertview" style="display:none">
<form id="frm" method="post">
<input type = "hidden" name = "id" value = "${mvo.id}">
<div class="form-group">
<label for="title">제목 :</label>
<input type="text" class="form-control" name="title" id="title">
</div>
<div class="form-group">
<label for="writer">작성자 :</label>
<input type="text" class="form-control" name="writer" id="writer" value="${mvo.name}" readonly="readonly">
</div>
<div class="form-group">
<label for="contents">내용 :</label>
<textarea rows = "10" class="form-control" name="contents" id="contents"></textarea>
</div>
<button type="button" onclick="boardInsert()" class="btn btn-primary btn-sm">글쓰기</button>
<button type="reset" class="btn btn-warning btn-sm close2">닫기</button>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
loadList(); // () 쓰면 호출, 안쓰면 참조
})
function loadList(){
$.ajax({
// 서버 url
url : '${cpath}/boardListAjax.do',
// 요청 방식
type : 'get',
// 받아올 데이터 타입 지정
dataType : 'json',
// 성공했을 때 실행할 함수
success : listView,
// 실패했을 때 실행할 함수
error : function(){
alert('실패!');
}
})
}
// 3. 화면에 보여주는 함수 생성
function listView(data){
console.log(data)
// 내가 화면에 출력해줄 tr 태그들의 모음
var blist = "";
// for-each문을 사용하는 방법
// $.each(어떤 데이터를 가지고 반복, 어떤 함수로 처리해줄건지)
$.each(data,function(index,board){
// function(인덱스번호,data안에 들어있는 각각의 값들을 어떤 변수로 받아줄 건지)
blist += "<tr class = 'innerContent'>"
blist += "<td>"+board.idx+"</td>"
blist += "<td><a href='javascript:viewContent("+board.idx+")'>"+board.title+"</a></td>"
blist += "<td>"+board.writer+"</td>"
blist += "<td>"+board.indate+"</td>"
if("${mvo.id}"==board.id){
blist += "<td><button onclick = 'boardDelete("+board.idx+")' class = 'btn-sm btn-warning btn'>삭제</button></td>"
}else{
blist += "<td><button disabled onclick = 'boardDelete("+board.idx+")' class = 'btn-sm btn-warning btn'>삭제</button></td>"
}
blist += "</tr>"
blist += "<tr class = 'innerContent' id = 'vc"+board.idx+"' style='display:none'>"
blist += "<td colspan = '5'>"
blist += "<textarea rows = '5' class = 'form-control'>"+board.contents+"</textarea>"
blist += "<br>"
if("${mvo.id}"==board.id){
blist += "<button onclick='boardUpdate("+board.idx+")' class = 'btn-success btn btn-sm'>수정</button>"
}else{
blist += "<button disabled onclick='boardUpdate("+board.idx+")' class = 'btn-success btn btn-sm'>수정</button>"
}
blist += " <button onclick='goClose("+board.idx+")' class = 'btn-warning btn btn-sm'>닫기</button>"
blist += "</td>"
blist += "</tr>"
})
// heading이라는 class 명을 가진 tr태그 다음에 blist를 추가하기!
$('.innerContent').remove();
$('.heading').after(blist);
}
function goInsert(){
if($('#insertview').css('display') == 'none'){
// $('#insertview').css('display','block');
$('#insertview').slideDown();
}else{
//$('#insertview').css('display','none');
$('#insertview').slideUp();
}
}
function boardInsert(){
// form 태그 안에 있는 input, textarea등에 name값이 달려있는 태그들의 값을 가져와서
// 직렬화시키는 함수
var formdata = $('#frm').serialize();
$.ajax({
// 서버 url
url : '${cpath}/boardInsert.do',
// 요청 방식
type : 'post',
// 데이터 전송
data : formdata,
// 성공했을 때 실행할 함수
success : loadList,
// 실패했을 때 실행할 함수
error : function(){
alert('실패!');
}
})
// 초기화 버튼을 한번 클릭!
$('.close2').trigger('click');
// insertview div태그를 다시 접어주기
$('#insertview').slideUp();
}
function boardDelete(idx){
$.ajax({
// 서버 url
url : '${cpath}/boardDelete.do',
// 요청 방식
type : 'get',
// 데이터 전송
data : {'idx':idx},
// 성공했을 때 실행할 함수
success : loadList,
// 실패했을 때 실행할 함수
error : function(){
alert('실패!');
}
})
}
function viewContent(idx){
if($('#vc'+idx).css('display') == 'none'){
$('#vc'+idx).css('display','table-row');
}else{
$('#vc'+idx).css('display','none');
}
}
function boardUpdate(idx){
var contents = $('#vc'+idx+' textarea').val();
$.ajax({
url : '${cpath}/boardUpdate.do',
type : 'get',
data : {'idx': idx,
'contents' : contents
},
success : loadList,
error : function(){
alert('실패!');
}
})
}
function goClose(idx){
console.log('#vc'+idx+'')
$('#vc'+idx+'').slideUp();
}
</script>
</body>
</html>
MemberVO
package kr.smhrd.model;
import lombok.Data;
@Data
public class MemberVO {
private String id;
private String pw;
private String name;
}
BoardController
package kr.smhrd.web;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import kr.smhrd.model.MemberVO;
import kr.smhrd.service.BoardService;
@Controller
public class BoardController {
@Autowired // DI
private BoardService service;
@RequestMapping("/")
public String basic() {
return "basic";
}
@RequestMapping("/login.do")
public String login(MemberVO vo, HttpSession session) {
// session, request, response 등등 내가 필요한 데이터들을
// 매개변수에 받오겠다! 라고 작성하면 spring framewrok가 자동으로 수집해준다.
MemberVO mvo = service.login(vo);
session.setAttribute("mvo", mvo);
return "redirect:/";
}
@RequestMapping("/logout.do")
public String logout(HttpSession session) {
session.invalidate(); // 무효화
return "redirect:/";
}
}
BoardService
package kr.smhrd.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import kr.smhrd.mapper.BoardMapper;
import kr.smhrd.model.BoardVO;
import kr.smhrd.model.MemberVO;
@Service
public class BoardService {
// Business Layer 담당하는 클래스
// 로직들을 다 가지고 있을 수 있게끔 하는 클래스
// ex) if문, for문을 활용해서 작업, 받아온 데이터들을 다른 형태로 바꿔주는 로직을 짜는 등등
// service안쪽에는 RequestMapping을 쓰지 않는다!!!
// 요청 --> FrontController --> Controller(RequestMapping) --> Service --> Mapper --> DB
@Autowired
private BoardMapper mapper;
public List<BoardVO> boardListAjax(Model model) {
// @ResponseBody
// : 응답에 대한 제어권이 client에게 전부 되돌아간다.
// : !!!! converter가 로드가 되어있지 않으면 작동 불가능 !!!
List<BoardVO> list = mapper.boardList();
// List --- GSON ---> JSON
// List --- jackson ---> JSON
// 스프링 프레임워크는 jackson 라이브러리를 로드해주기만 하면
// 자동으로 json 구조로 변환 시켜준다.
return list;
}
public void boardInsertAjax(BoardVO vo) {
mapper.boardInsert(vo);
}
public void boardDeleteAjax(int idx) {
mapper.boardDelete(idx);
}
public void boardUpdateAjax(BoardVO vo) {
mapper.boardUpdateAjax(vo);
}
public MemberVO login(MemberVO vo) {
MemberVO mvo = mapper.login(vo);
return mvo;
}
}
BoardMapper
package kr.smhrd.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import kr.smhrd.model.BoardVO;
import kr.smhrd.model.MemberVO;
public interface BoardMapper {
public List<BoardVO> boardList();
public void boardInsert(BoardVO vo);
@Select("select * from board2 where idx=#{idx}")
public BoardVO boardContent(int idx);
// 쿼리문이 간단하다면 위쪽에 annotation 추가해서 처리할 수 있다.
@Delete("delete from board2 where idx=#{idx}")
public void boardDelete(int idx);
public void boardUpdate(BoardVO vo);
@Update("update board2 set contents=#{contents}, indate=now() where idx=#{idx}")
public void boardUpdateAjax(BoardVO vo);
@Select("select * from member where id=#{id} and pw=#{pw}")
public MemberVO login(MemberVO vo);
}
'Java > Spring' 카테고리의 다른 글
[Spring] 게시판 설계 변경(3Tier) (0) | 2022.07.22 |
---|---|
[Spring] 게시판 글 내용 수정(jquery+ajax) (0) | 2022.07.20 |
[Spring] 게시판 글 내용보기(jquery+ajax) (0) | 2022.07.20 |
[Spring] 게시판 글 삭제(jquery+ajax) (0) | 2022.07.20 |
[Spring] 게시판 글쓰기(jquery+ajax) (0) | 2022.07.20 |