VueJS로 CURD 게시판 만들기 (코드만 정리)
부트캠프(END)/-Spring2022. 9. 16. 15:43
BoardVO.java(Class)
package doo.doo.vo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BoardVO {
private int no, hit;
private String name, subject, content, dbday;
}
BoardController.java (Class) - 단순 화면 이동
package doo.doo.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.*;
import doo.doo.dao.*;
import doo.doo.vo.*;
@Controller //화면 이동!
public class BoardController {
@Autowired
private BoardDAO dao;
@GetMapping("board/list.do")
public String board_list(String page, Model model) {
return "board/list";
}
@GetMapping("board/insert.do")
public String board_insert() {
return "board/insert";
}
@GetMapping("board/detail.do")
public String board_detail(int no, Model model) {
model.addAttribute("no", no);
return "board/detail";
}
@GetMapping("board/update.do")
public String board_update(int no, Model model) {
model.addAttribute("no", no);
return "board/update";
}
@GetMapping("board/delete.do")
public String board_delete(int no, Model model) {
model.addAttribute("no", no);
return "board/delete";
}
}
글 목록 출력
BoardMapper.java (Interface)
package doo.doo.mapper;
import java.util.*;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.apache.ibatis.annotations.Update;
import doo.doo.vo.*;
public interface BoardMapper {
@Select("SELECT no, subject, name, TO_CHAR(regdate,'YYYY-MM-DD') as dbday, hit, num " +
"FROM (SELECT no, subject, name, regdate, hit, rownum as num " +
"FROM (SELECT no, subject, name, regdate, hit " +
"FROM spring_board ORDER BY no DESC)) " +
"WHERE num BETWEEN #{start} AND #{end}")
public List < BoardVO > boardListData(Map map);
@Select("SELECT CEIL(COUNT(*)/10.0) FROM spring_board")
public int boardTotalPage();
}
BoardDAO.java (Class)
package doo.doo.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import doo.doo.mapper.BoardMapper;
import doo.doo.vo.BoardVO;
@Repository
public class BoardDAO {
@Autowired
private BoardMapper mapper;
public List < BoardVO > boardListData(Map map) {
return mapper.boardListData(map);
}
public int boardTotalPage() {
return mapper.boardTotalPage();
}
}
BoardRestController.java (Class) - 자바와 자바스크립트 융합
package doo.doo.web;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import doo.doo.dao.*;
import doo.doo.vo.*;
@RestController
public class BoardRestController {
@Autowired
private BoardDAO dao;
@GetMapping(value = "board/list_vue.do", produces = "text/plain;charset=UTF-8")
public String board_list_vue(String page) {
if (page == null)
page = "1";
int curpage = Integer.parseInt(page);
Map map = new HashMap();
int rowsize = 10;
int start = rowsize * curpage - rowsize + 1;
int end = rowsize * curpage;
map.put("start", start);
map.put("end", end);
List < BoardVO > list = dao.boardListData(map);
int totalpage = dao.boardTotalPage();
//Javascript로 데이터를 전송
String result = "";
try {
JSONArray arr = new JSONArray();
//[{no:"1",name:"kim",..},{...},..] 이렇게
int k = 0;
for (BoardVO vo: list) {
JSONObject obj = new JSONObject(); //==VO
//JSONObject에 값을 채워 JSONArray로 넘겨 주면 VO의 ArrayList와 동일하게 작동한다.
obj.put("no", vo.getNo());
obj.put("subject", vo.getSubject());
obj.put("name", vo.getName());
obj.put("dbday", vo.getDbday());
obj.put("hit", vo.getHit());
//맨 첫번째 객체에 페이지 정보를 담아 넘긴다.
if (k == 0) {
obj.put("curpage", curpage);
obj.put("totalpage", totalpage);
}
arr.add(obj);
k++;
}
result = arr.toJSONString();
} catch (Exception ex) {}
return result;
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.row1{
width:850px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
<h1 class="text-center">글 목록</h1>
<div class="row row1">
<table class="table">
<tr>
<td>
<a href="../board/insert.do" class="btn btn-sm btn-primary">새글</a>
</td>
</tr>
<tr>
<th width=10% class="text-center">번호</th>
<th width=45% class="text-center">제목</th>
<th width=15% class="text-center">작성자</th>
<th width=20% class="text-center">작성일</th>
<th width=10% class="text-center">조회수</th>
</tr>
<tr v-for="vo in board_list">
<td width=10% class="text-center">{{vo.no}}</td>
<td width=45%><a :href="'../board/detail.do?no='+vo.no">{{vo.subject}}</a></td>
<td width=15% class="text-center">{{vo.name}}</td>
<td width=20% class="text-center">{{vo.dbday}}</td>
<td width=10% class="text-center">{{vo.hit}}</td>
</tr>
</table>
<table class="table">
<tr>
<td class="text-center">
<input type=button value="이전" class="btn btn-sm btn-danger">
{{curpage}} page / {{totalpage}} pages
<input type=button value="다음" class="btn btn-sm btn-danger">
</td>
</tr>
</table>
</div>
</div>
<script>
new Vue({
el:'.container',
data:{
board_list:[],
curpage:1,
totalpage:0
},
mounted:function(){
axios.get("http://localhost:8080/web/board/list_vue.do",{
params:{
page:this.curpage
}
}).then(result=>{
this.board_list = result.data;
this.curpage = this.board_list[0].curpage;
this.totalpage = this.board_list[0].totalpage;
})
}
})
</script>
</body>
</html>
글 쓰기
BoardMapper.java (Interface)
@SelectKey(keyProperty = "no", resultType = int.class, before = true,
statement = "SELECT NVL(MAX(no)+1,1) as no FROM spring_board")
@Insert("INSERT INTO spring_board VALUES(#{no},#{name},#{subject},#{content},#{pwd},SYSDATE,0)")
public void boardInsert(BoardVO vo);
BoardDAO.java (Class)
public void boardInsert(BoardVO vo) {
mapper.boardInsert(vo);
}
BoardRestController.java (Class) - 자바와 자바스크립트 융합
@GetMapping(value = "board/insert_vue.do", produces = "text/plain;charset=UTF-8")
public String board_insert_vue(BoardVO vo) {
dao.boardInsert(vo);
return "OK";
}
insert.jsp
id, name 부여 필요없음. v-model에
form태그도 필요없음
:어쩌고는 v-bind:의 생략임
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.row1{
margin : 0px auto;
width : 900px;
}
h1{
text-align:center;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
<h1>글쓰기</h1>
<div class="row row1">
<table class="table">
<tr>
<th width=20% class="text-right">이름</th>
<td width=80%>
<input type=text v-model="name" ref="name" size=20 class="input-sm">
</td>
</tr>
<tr>
<th width=20% class="text-right">제목</th>
<td width=80%>
<input type=text v-model="subject" ref="subject" size=50 class="input-sm">
</td>
</tr>
<tr>
<th width=20% class="text-right">내용</th>
<td width=80%>
<textarea v-model="content" rows="10" cols="50" ref="content"></textarea>
</td>
</tr>
<tr>
<th width=20% class="text-right">비밀번호</th>
<td width=80%>
<input type=password v-model="pwd" ref="pwd" size=15 class="input-sm">
</td>
</tr>
<tr>
<td colspan="2" class="text-center">
<input type=button value="글쓰기" class="btn btn-sm btn-warning" v-on:click="boardWrite()">
<input type=button value="취소" class="btn btn-sm btn-danger"
onclick="javascript:history.back()">
</td>
</tr>
</table>
</div>
</div>
<script>
new Vue({
el:'.container',
data:{ //v-model의 입력값을 아래 변수에 채워라
name:'',
subject:'',
content:'',
pwd:''
},
methods:{
boardWrite:function(){
console.log("함수호출");
//유효성 검사
if(this.name.trim()==""){
//태그를 가져올 때는 ref를 이용해 가져옴
this.$refs.name.focus();
return;
}
if(this.subject.trim()==""){
this.$refs.subject.focus();
return;
}
if(this.content.trim()==""){
this.$refs.content.focus();
return;
}
if(this.pwd.trim()==""){
this.$refs.pwd.focus();
return;
}
console.log("유효성 검사 끝");
//전송
axios.get("http://localhost:8080/web/board/insert_vue.do",{
params:{
name:this.name,
subject:this.subject,
content:this.content,
pwd:this.pwd
}
}).then(result=>{
location.href="../board/list.do";
})
}
}
})
</script>
</body>
</html>
글 상세보기
BoardMapper.java (Interface)
@Update("UPDATE spring_board SET hit=hit+1 WHERE no=#{no}")
public void boardHitIncrement(int no);
@Select("SELECT no, subject, name, content, TO_CHAR(regdate,'YYYY-MM-DD') as dbday, hit " +
"FROM spring_board WHERE no=#{no}")
public BoardVO boardDetailData(int no);
BoardDAO.java (Class)
public BoardVO boardDetailData(int no) {
mapper.boardHitIncrement(no);
return mapper.boardDetailData(no);
}
BoardRestController.java (Class) - 자바와 자바스크립트 융합
@GetMapping(value = "board/detail_vue.do", produces = "text/plain;charset=UTF-8")
public String board_detail_vue(int no) {
String result = "";
BoardVO vo = dao.boardDetailData(no);
JSONObject obj = new JSONObject();
obj.put("no", vo.getNo());
obj.put("subject", vo.getSubject());
obj.put("content", vo.getContent());
obj.put("name", vo.getName());
obj.put("dbday", vo.getDbday());
obj.put("hit", vo.getHit());
result = obj.toJSONString();
return result;
}
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.row1{
margin: 0px auto;
width: 800px;
width : 650px;
}
h1{
text-align:center;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
<h1>상세보기</h1>
<div class="row row1">
<table class="table">
<tr>
<th width=20% class="text-center warning">번호</th>
<td width=30% class="text-center">{{vo.no}}</td>
<th width=20% class="text-center warning">작성일</th>
<td width=30% class="text-center">{{vo.dbday}}</td>
</tr>
<tr>
<th width=20% class="text-center warning">이름</th>
<td width=30% class="text-center">{{vo.name}}</td>
<th width=20% class="text-center warning">조회수</th>
<td width=30% class="text-center">{{vo.hit}}</td>
</tr>
<tr>
<th width=20% class="text-center warning">제목</th>
<td colspan="3">{{vo.subject}}</td>
</tr>
<tr>
<td colspan="4" class="text-left" valign="top" height="200">
<pre style="white-space:pre-wrap; border:none; background-color:white;">{{vo.content}}</pre>
</td>
</tr>
<tr>
<td colspan="4" class="text-right">
<a :href="'update.do?no='+no" class="btn btn-xs btn-info">수정</a>
<a href="#" class="btn btn-xs btn-success">답글</a>
<a :href="'delete.do?no='+vo.no" class="btn btn-xs btn-danger">삭제</a>
<a href="../board/list.do" class="btn btn-xs btn-primary">목록</a>
</td>
</tr>
</table>
</div>
</div>
<script>
new Vue({
el:'.container',
data:{
vo:{},
no:${no} //Controller에서 보내준거(EL)를 no에 넣어줌
},
mounted:function(){
let _this=this;
// 요청
axios.get("http://localhost:8080/web/board/detail_vue.do",{
params:{
no:_this.no
}
// 요청 처리 결과값 읽기 => 데이터값 변경 (상태변경) 상태 관리 프로그램
}).then(function(result){
_this.vo=result.data;
})
}
})
</script>
</body>
</html>
글 수정
BoardMapper.java (Interface)
@Select("SELECT pwd FROM spring_board WHERE no=#{no}")
public String boardGetPassword(int no);
@Update("UPDATE spring_board SET " +
"name=#{name}, subject=#{subject}, content=#{content} WHERE no=#{no}")
public String boardUpdate(BoardVO vo);
BoardDAO.java (Class)
public BoardVO boardUpdateData(int no) {
return mapper.boardDetailData(no);
}
public String boardUpdate(BoardVO vo) {
String result = "no";
String db_pwd = mapper.boardGetPassword(vo.getNo());
if (db_pwd.equals(vo.getPwd())) {
result = "yes";
mapper.boardUpdate(vo);
}
return result;
}
BoardRestController.java (Class) - 자바와 자바스크립트 융합
@GetMapping(value = "board/update_vue.do", produces = "text/plain;charset=UTF-8")
public String board_update_vue(int no) {
String result = "";
BoardVO vo = dao.boardUpdateData(no);
JSONObject obj = new JSONObject();
System.out.println(vo.getContent());
obj.put("no", vo.getNo());
obj.put("subject", vo.getSubject());
obj.put("content", vo.getContent());
obj.put("name", vo.getName());
result = obj.toJSONString();
return result;
}
@GetMapping(value = "board/update_vue_ok.do", produces = "text/plain;charset=UTF-8")
public String board_update_vue_ok(BoardVO vo) {
String result = dao.boardUpdate(vo);
return result;
}
update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.container{
margin-top: 50px;
}
.row{
margin : 0px auto;
width : 900px;
}
h1{
text-align:center;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript">
$(function(){
$('#writeBtn').click(function(){
let name = $('#name').val();
if(name.trim()==""){
$('#name').focus();
return;
}
let subject = $('#subject').val();
if(subject.trim()==""){
$('#subject').focus();
return;
}
let content = $('#content').val();
if(content.trim()==""){
$('#content').focus();
return;
}
let pwd = $('#pwd').val();
if(pwd.trim()==""){
$('#pwd').focus();
return;
}
$('#frm').submit();
})
})
</script>
</head>
<body>
<div class="container">
<h1>글 수정하기</h1>
<div class="row">
<form method=post action="update_ok.do" id="frm">
<table class="table">
<tr>
<th width=20% class="text-right">이름</th>
<td width=80%>
<input type=text name=name id=name size=20 class="input-sm" value="${vo.name }">
<input type=hidden name=no value=${vo.no }>
</td>
</tr>
<tr>
<th width=20% class="text-right">제목</th>
<td width=80%>
<input type=text name=subject id=subject size=50 class="input-sm" value="${vo.subject }">
</td>
</tr>
<tr>
<th width=20% class="text-right">내용</th>
<td width=80%>
<textarea rows="10" cols="50" name=content id=content>${vo.content }</textarea>
</td>
</tr>
<tr>
<th width=20% class="text-right">비밀번호</th>
<td width=80%>
<input type=password name=pwd id=pwd size=15 class="input-sm">
</td>
</tr>
<tr>
<td colspan="2" class="text-center">
<input type=button value="수정하기" class="btn btn-sm btn-warning" id="writeBtn">
<input type=button value="취소" class="btn btn-sm btn-danger"
onclick="javascript:history.back()">
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
글 삭제
BoardMapper.java (Interface)
@Delete("DELETE FROM spring_board WHERE no=#{no}")
public void boardDelete(int no);
BoardDAO.java (Class)
public String boardDelete(String pwd, int no) {
String result = "no";
String db_pwd = mapper.boardGetPassword(no);
if (db_pwd.equals(pwd)) {
result = "yes";
mapper.boardDelete(no);;
}
return result;
}
BoardRestController.java (Class) - 자바와 자바스크립트 융합
@GetMapping(value = "board/delete_vue_ok.do", produces = "text/plain;charset=UTF-8")
public String board_delete_vue_ok(String pwd, int no) {
String result = dao.boardDelete(pwd, no);
return result;
}
delete.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.row1{
margin : 0px auto;
width : 450px;
}
h1{
text-align:center;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
<h1>글 삭제하기</h1>
<div class="row row1">
<table class="table">
<tr>
<th width=20% class="text-right">비밀번호</th>
<td width=80%>
<input type=password v-model="pwd" ref="pwd" size=15 class="input-sm">
</td>
</tr>
<tr>
<td colspan="2" class="text-center">
<input type=submit value="삭제" class="btn btn-sm btn-warning" v-on:click="boardDelete()">
<input type=button value="취소" class="btn btn-sm btn-info" onclick="javascript:history.back()">
</td>
</tr>
</table>
</div>
</div>
<script>
new Vue({
el:'.container',
data:{
no:${no},
pwd:'',
res:''
},
methods:{
boardDelete:function(){
let _this=this;
axios.get("http://localhost:8080/web/board/delete_vue_ok.do",{
params:{
no:_this.no,
pwd:_this.pwd
}
}).then(function(result){
_this.res = result.data
if(_this.res=='yes'){
location.href="../board/list.do"
}else{
alert("비밀번호 확인하셈!!!");
_this.pwd = "";
_this.$refs.pwd.focus();
}
})
}
}
})
</script>
</body>
</html>
'부트캠프(END) > -Spring' 카테고리의 다른 글
VueJS로 검색 기능 만들기 (코드만 정리) (0) | 2022.09.16 |
---|---|
네이버 OpenAPI로 추천 기능 만들기 (0) | 2022.09.15 |
채팅 기능 만들기 (0) | 2022.09.15 |
댓글()