작년 12월에 네트워크관리사 2급 시험을 마친 후, 인프런에서 스프링 강의를 보며 공부했다.
시청한 강의는 김영한 선생님의 "스프링 입문"이었다. 해당 강의를 보며 따라한 페이지 만들기와, 유튜브로 조금 공부한 html과 css를 융합해 게시판이라 부르기 어려운 수준의 게시판을 만들었다. 개발 환경은 intellij를 사용했다.
이 글을 작성하는 이유는, 현재의 부족한 나와 실력과 경험을 더 쌓았을 훗날의 나를 비교하며 성장했다는 증거를 남기기 위함이다.
MySQL TABLE
create table board (
bno int not null auto_increment comment '일련번호',
title varchar(200) not null comment '제목',
content varchar(4000) comment '내용',
writer varchar(50) comment '작성자',
regdate date comment '작성일',
viewcnt int default 0 comment '조회수',
primary key(bno)
);
board라는 이름의 테이블에 일련번호, 제목, 내용, 작성자, 작성일, 조회수를 컬럼으로 넣었다.
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="board">
<select id="getList" resultType="com.board.start.api.board.vo.BoardVo">
SELECT bno
, title
, content
, writer
, regdate
, viewcnt
FROM board
</select>
<select id="getListByBno" resultType="com.board.start.api.board.vo.BoardVo" parameterType="com.board.start.api.board.vo.BoardVo">
SELECT bno
, title
, content
FROM board
WHERE bno = #{bno}
</select>
<insert id="createBoard" parameterType="com.board.start.api.board.vo.BoardVo">
INSERT INTO board
(title, content, writer)
values(#{title}, #{content}, #{writer})
</insert>
<update id="modifyBoard" parameterType="com.board.start.api.board.vo.BoardVo">
update board set title = #{title}, content = #{content} where bno = #{bno}
</update>
<delete id="deleteBoardByBno" parameterType="com.board.start.api.board.vo.BoardVo">
DELETE
FROM board
WHERE bno = #{bno}
</delete>
</mapper>
xml 파일을 테이블과 연동하고 select, insert, update, delete문을 넣어줬다.
BoardVo
package com.board.start.api.board.vo;
public class BoardVo {
long bno; //일렵번호
String title; //제목
String content; //내용
String writer; //작성자
String regdate; //작성일
int viewcnt; //조회수
public long getBno() {
return bno;
}
public void setBno(long bno) {
this.bno = bno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getRegdate() {
return regdate;
}
public void setRegDate(String regDate) {
this.regdate = regDate;
}
public int getViewcnt() {
return viewcnt;
}
public void setViewcnt(int viewcnt) {
this.viewcnt = viewcnt;
}
}
BoardDao
package com.board.start.api.board.dao;
import com.board.start.api.board.vo.BoardVo;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class BoardDao {
@Autowired
SqlSession sqlSession;
public List<BoardVo> getList() {
return sqlSession.selectList("board.getList");
}
public BoardVo getListByBno(int bno) {
BoardVo vo = new BoardVo();
vo.setBno(bno);
return sqlSession.selectOne("board.getListByBno", vo);
}
public int createBoard(BoardVo vo) {
return sqlSession.insert("board.createBoard", vo);
}
public int modifyBoard(BoardVo vo) {
return sqlSession.update("board.modifyBoard", vo);
}
public int deleteBoardByBno(int bno) {
BoardVo vo = new BoardVo();
vo.setBno(bno);
return sqlSession.delete("board.deleteBoardByBno", vo);
}
}
package com.board.start.api.board.service;
import com.board.start.api.board.dao.BoardDao;
import com.board.start.api.board.vo.BoardVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BoardService {
@Autowired
BoardDao dao;
public List<BoardVo> getList() {
return dao.getList();
}
public int createBoard(BoardVo vo) {
return dao.createBoard(vo);
}
public BoardVo getListByBno(int bno) {
return dao.getListByBno(bno);
}
public int modifyBoard(BoardVo vo) {
return dao.modifyBoard(vo);
}
public int deleteBoardByBno(int bno) {
return dao.deleteBoardByBno(bno);
}
}
BoardController
package com.board.start.api.board.controller;
import com.board.start.api.board.service.BoardService;
import com.board.start.api.board.vo.BoardVo;
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 org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@Controller
public class BoardController {
@Autowired
BoardService service;
public List<BoardVo> getList() {
return service.getList();
}
@GetMapping("/board")
public String indexBoard(Model model) {
List<BoardVo> list = service.getList();
model.addAttribute("list", list);
return "board";
}
@GetMapping("/post")
public String uploadPost() {
return "post/uploadPost";
}
@GetMapping("/board-post")
public String createBoard(PostForm form, Model model) {
BoardVo vo = new BoardVo();
vo.setContent(form.getContent());
vo.setTitle(form.getTitle());
vo.setWriter(form.getWriter());
service.createBoard(vo);
return "redirect:/board";
}
@GetMapping("/modify/{bno}")
public String modifyPost(@PathVariable("bno")int bno, Model model) {
model.addAttribute("bno", bno);
BoardVo vo = service.getListByBno(bno);
model.addAttribute("board", vo);
return "post/modify";
}
@GetMapping("/modify-board")
public String modifyBoard(PostForm form, Model model, int bno) {
BoardVo vo = new BoardVo();
vo.setContent(form.getContent());
vo.setTitle(form.getTitle());
vo.setBno(form.getBno());
service.modifyBoard(vo);
List<BoardVo> list = service.getList();
model.addAttribute("list", list);
return "/board";
}
@GetMapping("/delete-board/{bno}")
public String deleteBoardByBno(@PathVariable("bno") int bno, Model model) {
service.deleteBoardByBno(bno);
return "redirect:/board";
}
}
BoardForm
package com.board.start.api.board.controller;
public class PostForm {
String title; //제목
String content; //내용
String writer; //작성자
long bno;
public long getBno() {
return bno;
}
public void setBno(long bno) {
this.bno = bno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
}
board.html
<!DOCTYPE html>
<html lang="en">
<head>
<style rel="stylesheet">
*{
margin: 10px auto;
padding: 10px auto;
text-decoration none;
text-align: center;
}
html{
font-size: 20px;
}
a {
text-decoration none;
color inherit;
}
.board-wrap{
width: 100px auto;
margin: 50px auto;
padding: 30px auto;
}
.board-title h1{
font-size: 2rem;
}
.board-list{
width 100px;
border-top: 2px solid #000;
text-align: center;
}
.board-list a{
border: 1px solid #000;
}
.button-wrap{
margin-top: 30px;
text-align: center;
}
.button-wrap a {
min-width: 80px;
padding: 10px;
border: 1px solid #000;
border-radius: 2px;
}
.button-wrap a.on{
background: #000;
color: #fff;
}
</style>
<meta charset="UTF-8">
<title>게시판</title>
</head>
<body>
<div class="board-wrap">
<h1>게시판</h1>
<div class="board-list">
<table border="1">
<thead>
<th>일련번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>수정</th>
<th>삭제</th>
</thead>
<tbody>
<tr th:each="vo : ${list}">
<td th:text="${vo.bno}"></td>
<td th:text="${vo.title}"></td>
<td th:text="${vo.writer}"></td>
<td th:text="${vo.regdate}"></td>
<td>
<a href="#" th:href="@{modify/{bno} (bno=${vo.bno})}" role="button">수정 </a>
</td>
<td>
<a href="#" th:href="@{delete-board/{bno} (bno=${vo.bno})}" role="button">삭제</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="button-wrap">
<a href="/post" class="on">게시물 등록</a>
</div>
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script th:inline="javascript">
</script>
uploadpost.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<style>
*{
text-align: center;
}
.form-group{
margin: 40px auto;
width: 40px auto;
border-top: 2px solid #000;
text-align: center;
}
.form-group table{
text-align: center;
}
table{
border: 2px solid #000;
text-align: center;
margin-left: 750px;
margin-top: 50px;
margin-bottom:50px;
}
.container button{
text-align: center;
border: 1px solid #000;
padding: 10px;
}
.form-group tr{
border: 2px solid #000;
text-align: center;
}
</style>
<meta charset="UTF-8">
<title>게시물 등록</title>
</head>
<body>
<div class="container">
<h1>게시물 등록</h1>
<form action="/board-post">
<div class="form-group">
<table>
<tr>
<td>제목</td>
<td><input type="text" id="title" name="title" placeholder="제목을 입력하세요"></td>
</tr>
<tr>
<td>내용</td>
<td><input type="text" id="content" name="content" placeholder="내용을 입력하세요"></td>
</tr>
<tr>
<td>작성자</td>
<td><input type="text" id="writer" name="writer" placeholder="작성자"></td>
</tr>
</table>
</div>
<button type="submit">등록</button>
</form>
</div> <!--/container-->
</body>
</html>
modify.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<style rel="stylesheet">
*{
text-align: center;
}
.form-group{
margin: 40px auto;
width: 40px auto;
border-top: 2px solid #000;
text-align: center;
}
.form-group table{
text-align: center;
}
table{
border: 2px solid #000;
text-align: center;
margin-left: 750px;
margin-top: 50px;
margin-bottom:50px;
}
.container button{
text-align: center;
border: 1px solid #000;
padding: 10px;
}
.form-group tr{
border: 2px solid #000;
text-align: center;
}
</style>
<meta charset="UTF-8">
<title>수정</title>
</head>
<body>
<div class="container">
<h1>게시물 수정</h1>
<form action="/modify-board" th:object="${board}">
<div class="form-group">
<table>
<input type="hidden" th:field="*{bno}">
<tr>
<td>제목</td>
<td><input type="text" id="title" name="title" th:field="*{title}"></td>
</tr>
<tr>
<td>내용</td>
<td><input type="text" id="content" name="content" th:field="*{content}"></td>
</tr>
</table>
</div>
<button type="submit">수정</button>
</form>
</div>
</body>
</html>
localhost:8080/board

localhost:8080/modify


localhost:8080/post


삭제


본인이 봐도 기능에 있어 아쉬움이 많고 아직 CSS를 능숙히 다루지 못하는 것이 느껴진다. 하지만 애정을 갖고 만들어서인지 콩깍지가 껴 이쁘게만 보인다. 열심히 정진하여 좋은 개발자, 좋은 동료가 될 그 날까지 나 자신, 이 글을 보는 시기에 공부하는 개발 초보 여러분들에게 응원과 용기를 불어넣고 싶다.
긴 글 봐주셔서 감사합니다.