👀 홈페이지의 기본인 게시판 만들기 !! 👀
게시판 테이블은 이전에 제작해둔 spring_board 테이블을 이용했다.
CREATE TABLE spring_board(
no NUMBER,
cno NUMBER,
type NUMBER,
id VARCHAR2(20),
name VARCHAR2(34) CONSTRAINT sr3_name_nn NOT NULL,
msg CLOB CONSTRAINT sr3_msg_nn NOT NULL,
regdate DATE DEFAULT SYSDATE,
)
아마 이정도로 테이블을 만든 것 같음..(코드 어딨는지 모르게써😨)
package com.sist.vo;
import java.util.Date;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class BoardVO {
private int no,hit;
private String name,subject,content,dbday;
private Date regdate;
}
VO 폴더에 BoardVO를 만들고, 해당코드를 작성했다😆
Getter/Setter은 lombok의 라이브러리를 사용했는데,
없으면 그냥 Source => Generated Getters and Setter 사용하면 된다~~
package com.sist.mapper;
import java.util.*;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import com.sist.vo.BoardVO;
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 ORDEY 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();
@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);
}
가장 기본적인 게시판 리스트보기, Pagination, 글쓰기(Insert) 기능만 만들기 위한 코드를 작성했다~~
CEIL(COUNT(*)/10.0) => 게시판 글을 10개씩 잘라서 Pagination
SELECT NVL(MAX(no)+1,1) as no FROM spring_board => Sequence 구문
실제 현업에서는 Controller와 RestController를 따로 구분하지 않는다고 하시던데.. 흠
여튼 지금 코드에서는 RestController와 Controller를 구분해서 사용한다.
RestController => 데이터 전송 용도(JSON)
Controller => 화면 변환 용도
@Controller
public class BoardController {
@Autowired
private BoardDAO dao;
//사용자 요청 받기 => URI를 통하여 사용자의 요청을 받음
@GetMapping("board/list.do")
//사용자에게 받은 주소가 board/list.do 라면 어떤 역할을 수행할건지??
public String board_list()
{
return "board/list";
}
@GetMapping("board/insert.do")
public String board_insert()
{
return "board/insert";
}
}
GetMapping => URI를 통하여 사용자의 요청을 받기위해 사용한다.
쉽게 말해서, 사용자의 요청은 다른 것으로는 받을 수 없고 주소를 통해서만 받을 수 있다고
한다!! 그래서 GetMapping을 이용해 주소를 받는거다 😋
위 코드처럼 @GetMapping("board/list.do") 의 경우 ..
=> 사용자에게 받은 주소가 board/list.do 라면 어떤 역할을 수행할건지?? 이렇게 해석된다!
마지막으로 return "board/list" 는 코드가 실행된 후 반환될 페이지라고 생각하면 될것같다.
@RestController
public class BoardRestController {
@Autowired
private BoardDAO dao;
//VueJS에서 페이지 전송
@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
{
//list보낼때 => Array 사용(JSONArray)
//vo보낼때 => object 사용(JSONObject)
//==> Javascript의 공식
//object에 있는거 10개를 list에 모아라!(10개씩 나누기로 했으니까)
JSONArray arr=new JSONArray();
int k=0;
for(BoardVO vo:list)
{
JSONObject obj=new JSONObject();
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;
}
@GetMapping(value = "board/insert_vue.do",produces = "text/plain;charset=utf-8")
public String board_insert_vue(BoardVO vo)
{
dao.boardInsert(vo);
return "OK";
}
}
JSONObject obj=new JSONObject() => VO를 받을 때 사용한다
JSONArray arr=new JSONArray() => list를 받을 때 사용한다
⭐️ 이걸로 받아야 Vue가 값을 인식 한다고 한다.
⭐️ 다음 코드와 같이 10개의 게시판을 동시에 보내야 할때는,
JSONObject로 값을 하나씩 받고, JSONArray로 값을 묶어서 저장해주면 된다.
VueJS를 이용해서 화면 구상 시작!!
코드를 입력<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- Vue를 이용한 코딩 => JSTL,EL 필요없음(for문 돌릴필요없음) -->
<!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">VueJS를 이용한 목록 출력</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>
<!-- VueJS의 for문 -->
<tr v-for="vo in board_list">
<th width=10% class="text-center">{{vo.no}}</th>
<th width=45%>{{vo.subject}}</th>
<th width=15% class="text-center">{{vo.name}}</th>
<th width=20% class="text-center">{{vo.dbday}}</th>
<th width=10% class="text-center">{{vo.hit}}</th>
</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
el:'.container',
data:{
board_list:[],
curpage:1,
totalpage:0
},
mounted:function(){
let _this=this;
axios.get("http://localhost:8080/web/board/list_vue.do",{
params:{
page:_this.curpage
}
}).then(function(result){
//개발자도구창에서 넘어온값 확인가능
console.log(result.data);
_this.board_list=result.data;
_this.curpage=result.data[0].curpage;
_this.totalpage=result.date[0].totalpage;
})
}
})
</script>
</body>
</html>
⭐️ ajax와 Vue 다른점 ⭐️
그리고 Vue쓰려면 해당 구문을 넣어줘야한다 !
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
el:'.container' => 관리 영역 지정(나는 모든 구문을 제어 할 것이고, 구문들을 Container로
감싸줬기때문에 이렇게 썼다!
mounted:function() => 버튼을 클릭하거나 엔터를 치거나 이런 동작 없이 시작과 동시에
값을 가져온다.
console.log(result.data) => 값 잘넘어왔는지 '개발자도구' 창에서 확인 할수있게 하는 코드!
<%@ 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: 700px;
}
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" size=20 class="input-sm" ref="name">
</td>
</tr>
<tr>
<th width=20% class="text-right">제목</th>
<td width=80%>
<input type=text v-model="subject" size=50 class="input-sm" ref="subject">
</td>
</tr>
<tr>
<th width=20% class="text-right">내용</th>
<td width=80%>
<textarea rows="10" cols="50" v-model="content" ref="content"></textarea>
</td>
</tr>
<tr>
<th width=20% class="text-right">비밀번호</th>
<td width=80%>
<input type=password v-model="pwd" size=15 class="input-sm" ref="pwd">
</td>
</tr>
<tr>
<td colspan="2" class="text-center">
<input type=button value="글쓰기" class="btn btn-sm btn-warning" v-on:click="boardWrite()">
<%--
v-on:click="aaa()"
@click="aaa()"
--%>
<input type=button value="취소" class="btn btn-sm btn-info"
onclick="javascript:history.back()">
</td>
</tr>
</table>
</div>
</div>
<script>
//입력하면 멤버변수 안에 값을 채워줌(name,subject...)
new Vue({
el:'.container',
data:{
name:'',
subject:'',
content:'',
pwd:''
},
methods:{
boardWrite:function(){
//this 안붙이면 지역변수로 인식 => this 꼭 붙이기
//유효성 검사 ) => 값이 공백이면 포커스 잡아줌
if(this.name.trim()=="")
{
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;
}
//전송
axios.get("http://localhost:8080/web/board/insert_vue.do",{
//값 채워주기
params:{
name:this.name,
subject:this.subject,
content:this.content,
pwd:this.pwd
}
}).then(function(result){
location.href="../board/list.do";
})
}
}
})
</script>
</body>
</html>
게시판 글 작성 페이지
작성 완료 후 모습!!!😝
Pagination은 고쳐야겠당 ..