일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 예외미루기
- 자바
- Java
- abstract
- exception
- 추상메서드
- 객체 비교
- 다형성
- 대덕인재개발원
- 메소드오버로딩
- 인터페이스
- 예외처리
- 참조형변수
- cursor문
- 한국건설관리시스템
- 집합_SET
- 어윈 사용법
- GRANT VIEW
- 컬렉션 타입
- 정수형타입
- 컬렉션프레임워크
- 오라클
- 사용자예외클래스생성
- NestedFor
- oracle
- 환경설정
- 제네릭
- EnhancedFor
- 생성자오버로드
- 자동차수리시스템
- Today
- Total
거니의 velog
231121_SPRING 1 (5-2) - 자유게시판 과제 본문
-- SPRING 1
-- FREE 테이블 생성
create table free(
free_no number not null,
free_title varchar2(300) not null,
free_content varchar2(3000) not null,
free_writer varchar2(150) not null,
free_date date not null,
free_hit number(8) default 0 null,
constraint pk_free primary key(free_no)
);
-- FREE 테이블 시퀀스 생성
CREATE SEQUENCE seq_free
INCREMENT by 1
start with 1
nocache;
commit;
select * from free;
-- SPRING 1
-- NOTICE 테이블 생성
create table notice(
notice_no number not null,
notice_title varchar2(300) not null,
notice_content varchar2(3000) not null,
notice_writer varchar2(150) not null,
notice_date date not null,
notice_hit number(8) default 0 null,
constraint pk_notice primary key(notice_no)
);
-- NOTICE 테이블 시퀀스 생성
CREATE SEQUENCE seq_notice
INCREMENT by 1
start with 1
nocache;
commit;
select * from notice;
select *
from (
select
bono, botitle, bocontent, bowriter, bodate, bohit
from board
order by bono desc
)
where rownum <= 5;
[board_SQL.xml]
<select id="selectBoardList_" resultType="boardVO">
<![CDATA[
select *
from (
select
bono, botitle, bocontent, bowriter, bodate, bohit
from board
order by bono desc
)
where rownum <= 5
]]>
</select>
[MainController.java]
package kr.or.ddit.main.web;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.vo.BoardVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Controller
public class MainController {
@Inject
private IBoardService boardService;
@RequestMapping(value = { "/", "/main.do" }, method = RequestMethod.GET)
public String main(Model model) {
PaginationInfoVO<BoardVO> boardPagingVO = new PaginationInfoVO<BoardVO>();
List<BoardVO> boardList5 = boardService.selectBoardList_();
int boardTotalRecord = boardService.selectBoardCount(boardPagingVO);
model.addAttribute("boardList5", boardList5);
model.addAttribute("boardTotalRecord", boardTotalRecord);
return "main";
}
}
[main.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.*"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<title>메인화면</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z" />
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h1 class="display-4 fw-normal">게시판 작성 연습</h1>
<p class="lead fw-normal">Spring framework를 이용한 게시판 CRUD Example</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-6">
<div align="left">
<h5>일반 게시판</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 ${boardTotalRecord }건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<c:choose>
<c:when test="${empty boardList5 }">
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${boardList5 }" var="board">
<tr>
<td>${board.boNo }</td>
<td>
<a href="/board/detail.do?boNo=${board.boNo }">${board.boTitle }</a>
</td>
<td>${board.boDate }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
</div>
</form>
<a href="/board/list.do" class="btn btn-outline-primary">«더보기</a>
</div>
<div class="col-md-6">
<div align="left">
<h5>공지사항</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 0건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</form>
<a href="" class="btn btn-outline-primary">«더보기</a>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6">
<div align="left">
<h5>자유 게시판</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 0건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</form>
<a href="" class="btn btn-outline-primary">«더보기</a>
</div>
<div class="col-md-6"></div>
</div>
<br />
</div>
</main>
</body>
</html>
- http://localhost/main.do
[FreeVO.java]
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class FreeVO {
private int freeNo;
private String freeTitle;
private String freeContent;
private String freeWriter;
private String freeDate;
private int freeHit;
}
[mybatisAlias.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<typeAliases>
<typeAlias type="kr.or.ddit.vo.BoardVO" alias="boardVO" />
<typeAlias type="kr.or.ddit.vo.PaginationInfoVO" alias="pagingVO" />
<typeAlias type="kr.or.ddit.vo.FreeVO" alias="freeVO" />
</typeAliases>
</configuration>
[FreeRetreiveController.java]
package kr.or.ddit.free.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/free")
public class FreeRetreiveController {
@RequestMapping(value = "/list.do", method = RequestMethod.GET)
public String freeList() {
return "free/list";
}
}
- http://localhost/free/list.do
[form.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/resources/ckeditor/ckeditor.js"></script>
<title>자유게시판 등록/수정</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<c:set value="등록" var="name" />
<c:if test="${status eq 'u' }">
<c:set value="수정" var="name" />
</c:if>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z" />
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-body">
<form method="post" action="/free/insert.do" id="boardForm" name="boardForm" class="form-horizontal">
<div class="form-group row">
<label class="col-sm-2 control-label">제목</label>
<div class="col-sm-10">
<input id="freeTitle" name="freeTitle" type="text" class="form-control" value="${free.freeTitle }" placeholder="subject">
</div>
<font color="red" style="font-size: 12px;">${errors.freeTitle }</font>
</div>
<div class="form-group row mt-4">
<label class="col-sm-2 control-label">내용</label>
<div class="col-sm-10">
<textarea id="freeContent" name="freeContent" cols="50" rows="5" class="form-control" placeholder="content">${free.freeContent }</textarea>
</div>
<font color="red" style="font-size: 12px;">${errors.freeContent }</font>
</div>
<div class="form-group row mt-4">
<div class="col-sm-offset-2 col-sm-12 ">
<input type="button" value="${name }" class="btn btn-primary float-right" id="addBtn">
<c:if test="${status eq 'u' }">
<input type="button" value="취소" class="btn btn-danger float-right" id="cancelBtn">
</c:if>
<c:if test="${status ne 'u' }">
<input type="button" value="목록" class="btn btn-success float-right" id="listBtn">
</c:if>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-12"><br /><br /><br /></div>
</div>
</div>
</main>
</body>
<script type="text/javascript">
$(function(){
CKEDITOR.replace("freeContent"); // CKEDITOR를 textarea에 등록
var addBtn = $("#addBtn"); // 등록 버튼
var cancelBtn = $("#cancelBtn"); // 취소 버튼
var listBtn = $("#listBtn"); // 목록 버튼
var freeTitle = $("#freeTitle");
var freeContent = $("#freeContent");
var boardForm = $("#boardForm"); // 등록 form
// 등록 버튼 이벤트
addBtn.on("click", function(){
var title = freeTitle.val(); // 제목 데이터
// CKEDITOR를 사용해서 데이터를 가져와야 할 때 사용하는 방법(editor 사용 시)
var content = CKEDITOR.instances.freeContent.getData(); // 내용 데이터
// 제목을 입력하지 않았을 때 발생할 이벤트
if(!title) {
alert("제목을 입력해주세요!");
freeTitle.focus();
return false;
}
// 내용을 입력하지 않았을 때 발생할 이벤트
if(!content) {
alert("내용을 입력해주세요!");
freeContent.focus();
return false;
}
boardForm.submit();
});
// 취소 버튼 이벤트
cancelBtn.on("click", function(){
location.href = "/free/detail.do?freeNo=${board.freeNo}";
});
// 목록 버튼 이벤트
listBtn.on("click", function(){
location.href = "/free/list.do";
});
});
</script>
</html>
[IFreeService.java]
package kr.or.ddit.free.service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import kr.or.ddit.vo.FreeVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
</mapper>
[FreeInsertController.java]
package kr.or.ddit.free.web;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
@Controller
@RequestMapping("/free")
public class FreeInsertController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/form.do", method = RequestMethod.GET)
public String freeForm() {
return "free/form";
}
@RequestMapping(value = "/insert.do", method = RequestMethod.POST)
public String freeInsert(FreeVO freeVO, Model model) {
String goPage = "";
Map<String, String> errors = new HashMap<String, String>();
if(StringUtils.isBlank(freeVO.getFreeTitle())) {
errors.put("freeTitle", "제목을 입력해 주세요!");
}
if(StringUtils.isBlank(freeVO.getFreeContent())) {
errors.put("freeContent", "내용을 입력해 주세요!");
}
if(errors.size() > 0) { // 에러가 있음
model.addAttribute("free", freeVO);
model.addAttribute("errors", errors);
goPage = "free/form"; // 포워딩
}else { // 에러가 없는 정상적인 데이터 입력
freeVO.setFreeWriter("b001");
ServiceResult result = freeService.insertFree(freeVO);
if(result.equals(ServiceResult.OK)) {
goPage = "redirect:/free/detail.do?freeNo=" + freeVO.getFreeNo();
}else {
model.addAttribute("free", freeVO);
model.addAttribute("message", "서버 에러, 다시 시도해 주세요!");
goPage = "free/form"; // 포워딩
}
}
return goPage;
}
}
[form.jsp]
<form method="post" action="/free/insert.do" id="boardForm" name="boardForm" class="form-horizontal">
<div class="form-group row">
<label class="col-sm-2 control-label">제목</label>
<div class="col-sm-10">
<input id="freeTitle" name="freeTitle" type="text" class="form-control" value="${free.freeTitle }" placeholder="subject">
</div>
<font color="red" style="font-size: 12px;">${errors.freeTitle }</font>
</div>
<div class="form-group row mt-4">
<label class="col-sm-2 control-label">내용</label>
<div class="col-sm-10">
<textarea id="freeContent" name="freeContent" cols="50" rows="5" class="form-control" placeholder="content">${free.freeContent }</textarea>
</div>
<font color="red" style="font-size: 12px;">${errors.freeContent }</font>
</div>
<div class="form-group row mt-4">
<div class="col-sm-offset-2 col-sm-12 ">
<input type="button" value="등록" class="btn btn-primary float-right" id="addBtn">
<input type="button" value="취소" class="btn btn-danger float-right" id="cancelBtn">
<input type="button" value="목록" class="btn btn-success float-right" id="listBtn">
</div>
</div>
</form>
- http://localhost/free/form.do
[FreeRetreiveController.java]
package kr.or.ddit.free.web;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
@Controller
@RequestMapping("/free")
public class FreeRetreiveController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/list.do", method = RequestMethod.GET)
public String freeList() {
return "free/list";
}
@RequestMapping(value = "/detail.do", method = RequestMethod.GET)
public String freeDetail(int freeNo, Model model) {
FreeVO freeVO = freeService.selectFree(freeNo);
model.addAttribute("free", freeVO);
return "free/view";
}
}
[IFreeService.java]
package kr.or.ddit.free.service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import kr.or.ddit.vo.FreeVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
</mapper>
[view.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="${pageContext.request.contextPath}/resources/plugins/jquery/jquery.min.js"></script>
<title>자유게시판 등록/수정</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"/>
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"/>
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div
class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-header">
<h3 class="card-title">${free.freeTitle }</h3>
<div class="card-tools mt-1">
${free.freeWriter } ${free.freeDate } ${free.freeHit }
</div>
</div>
<div class="card-body">
<div class="form-group row mt-1">
<div class="col-sm-12">${free.freeContent }</div>
</div>
</div>
<div class="card-footer">
<button type="button" class="btn btn-primary" id="listBtn">목록</button>
<button type="button" class="btn btn-info" id="modifyBtn">수정</button>
<button type="button" class="btn btn-danger" id="delBtn">삭제</button>
</div>
</div>
</div>
<div class="col-md-12"><br/><br/><br/></div>
</div>
</div>
</main>
</body>
</html>
- http://localhost/free/detail.do?freeNo=5
[view.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<title>자유게시판 등록/수정</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z" />
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-header">
<h3 class="card-title">${free.freeTitle }</h3>
<div class="card-tools mt-1">
${free.freeWriter } ${free.freeDate } ${free.freeHit }
</div>
</div>
<div class="card-body">
<div class="form-group row mt-1">
<div class="col-sm-12">${free.freeContent }</div>
</div>
</div>
<div class="card-footer">
<button type="button" class="btn btn-primary" id="listBtn">목록</button>
<button type="button" class="btn btn-info" id="modifyBtn">수정</button>
<button type="button" class="btn btn-danger" id="delBtn">삭제</button>
</div>
<form action="/free/update.do" method="get" id="boardForm" name="boardForm">
<input type="hidden" name="freeNo" value="${free.freeNo }" />
</form>
</div>
</div>
<div class="col-md-12"><br /><br /><br /></div>
</div>
</div>
</main>
</body>
<script type="text/javascript">
$(function(){
var boardForm = $("#boardForm");
var listBtn = $("#listBtn");
var modifyBtn = $("#modifyBtn");
var delBtn = $("#delBtn");
// 목록 버튼 이벤트
listBtn.on("click", function(){
location.href = "/free/list.do"
});
// 수정 버튼 이벤트
modifyBtn.on("click", function(){
boardForm.submit();
});
// 삭제 버튼 이벤트
delBtn.on("click", function(){
if(confirm("정말로 삭제하시겠습니까?")){
boardForm.attr("action", "/free/delete.do");
boardForm.attr("method", "post");
boardForm.submit();
}
});
});
</script>
</html>
[FreeModifyController.java]
package kr.or.ddit.free.web;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
@Controller
@RequestMapping("/free")
public class FreeModifyController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/update.do", method = RequestMethod.GET)
public String FreeUpdateForm(int freeNo, Model model) {
FreeVO freeVO = freeService.selectFree(freeNo);
model.addAttribute("free", freeVO);
model.addAttribute("status", "u");
return "free/form";
}
@RequestMapping(value = "/update.do", method = RequestMethod.POST)
public String boardUpdate(FreeVO freeVO, Model model) {
String goPage = "";
ServiceResult result = freeService.updateFree(freeVO);
if(result.equals(ServiceResult.OK)) { // 수정 성공
goPage = "redirect:/free/detail.do?freeNo=" + freeVO.getFreeNo();
}else { // 수정 실패
model.addAttribute("free", freeVO);
model.addAttribute("status", "u");
goPage = "free/form";
}
return goPage;
}
}
[form.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/resources/ckeditor/ckeditor.js"></script>
<title>자유게시판 등록/수정</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<c:set value="등록" var="name" />
<c:if test="${status eq 'u' }">
<c:set value="수정" var="name" />
</c:if>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z" />
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-body">
<form method="post" action="/free/insert.do" id="boardForm" name="boardForm" class="form-horizontal">
<c:if test="${status eq 'u' }">
<input type="hidden" name="freeNo" value="${free.freeNo }" />
</c:if>
<div class="form-group row">
<label class="col-sm-2 control-label">제목</label>
<div class="col-sm-10">
<input id="freeTitle" name="freeTitle" type="text" class="form-control" value="${free.freeTitle }" placeholder="subject">
</div>
<font color="red" style="font-size: 12px;">${errors.freeTitle }</font>
</div>
<div class="form-group row mt-4">
<label class="col-sm-2 control-label">내용</label>
<div class="col-sm-10">
<textarea id="freeContent" name="freeContent" cols="50" rows="5" class="form-control" placeholder="content">${free.freeContent }</textarea>
</div>
<font color="red" style="font-size: 12px;">${errors.freeContent }</font>
</div>
<div class="form-group row mt-4">
<div class="col-sm-offset-2 col-sm-12 ">
<input type="button" value="${name }" class="btn btn-primary float-right" id="addBtn">
<c:if test="${status eq 'u' }">
<input type="button" value="취소" class="btn btn-danger float-right" id="cancelBtn">
</c:if>
<c:if test="${status ne 'u' }">
<input type="button" value="목록" class="btn btn-success float-right" id="listBtn">
</c:if>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-12"><br /><br /><br /></div>
</div>
</div>
</main>
</body>
<script type="text/javascript">
$(function(){
CKEDITOR.replace("freeContent"); // CKEDITOR를 textarea에 등록
var addBtn = $("#addBtn"); // 등록 버튼
var cancelBtn = $("#cancelBtn"); // 취소 버튼
var listBtn = $("#listBtn"); // 목록 버튼
var freeTitle = $("#freeTitle");
var freeContent = $("#freeContent");
var boardForm = $("#boardForm"); // 등록 form
// 등록 버튼 이벤트
addBtn.on("click", function(){
var title = freeTitle.val(); // 제목 데이터
// CKEDITOR를 사용해서 데이터를 가져와야 할 때 사용하는 방법(editor 사용 시)
var content = CKEDITOR.instances.freeContent.getData(); // 내용 데이터
// 제목을 입력하지 않았을 때 발생할 이벤트
if(!title) {
alert("제목을 입력해주세요!");
freeTitle.focus();
return false;
}
// 내용을 입력하지 않았을 때 발생할 이벤트
if(!content) {
alert("내용을 입력해주세요!");
freeContent.focus();
return false;
}
// 수정일 때, 경로를 변경한다. (기존은 등록 경로로 설정되어 있음)
if($(this).val() == "수정"){
boardForm.attr("action", "/free/update.do");
}
boardForm.submit();
});
// 취소 버튼 이벤트
cancelBtn.on("click", function(){
location.href = "/free/detail.do?freeNo=${free.freeNo}";
});
// 목록 버튼 이벤트
listBtn.on("click", function(){
location.href = "/free/list.do";
});
});
</script>
</html>
[IFreeService.java]
package kr.or.ddit.free.service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
public ServiceResult updateFree(FreeVO freeVO);
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
@Override
public ServiceResult updateFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.updateFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import kr.or.ddit.vo.FreeVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
public int updateFree(FreeVO freeVO);
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
@Override
public int updateFree(FreeVO freeVO) {
return sqlSession.update("Free.updateFree", freeVO);
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
<update id="updateFree" parameterType="freeVO">
update free
set
free_title = #{freeTitle},
free_content = #{freeContent},
free_date = sysdate
where free_no = #{freeNo}
</update>
</mapper>
- http://localhost/free/update.do?freeNo=146
[FreeModifyController.java]
package kr.or.ddit.free.web;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
@Controller
@RequestMapping("/free")
public class FreeModifyController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/update.do", method = RequestMethod.GET)
public String freeUpdateForm(int freeNo, Model model) {
FreeVO freeVO = freeService.selectFree(freeNo);
model.addAttribute("free", freeVO);
model.addAttribute("status", "u");
return "free/form";
}
@RequestMapping(value = "/update.do", method = RequestMethod.POST)
public String freeUpdate(FreeVO freeVO, Model model) {
String goPage = "";
ServiceResult result = freeService.updateFree(freeVO);
if(result.equals(ServiceResult.OK)) { // 수정 성공
goPage = "redirect:/free/detail.do?freeNo=" + freeVO.getFreeNo();
}else { // 수정 실패
model.addAttribute("free", freeVO);
model.addAttribute("status", "u");
goPage = "free/form";
}
return goPage;
}
@RequestMapping(value = "/delete.do", method = RequestMethod.POST)
public String deleteFree(int freeNo, Model model) {
String goPage = "";
ServiceResult result = freeService.deleteFree(freeNo);
if(result.equals(ServiceResult.OK)) { // 삭제 성공
goPage = "redirect:/free/list.do";
}else {
goPage = "redirect:/free/detail.do?freeNo=" + freeNo;
}
return goPage;
}
}
[IFreeService.java]
package kr.or.ddit.free.service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
public ServiceResult updateFree(FreeVO freeVO);
public ServiceResult deleteFree(int freeNo);
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
@Override
public ServiceResult updateFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.updateFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public ServiceResult deleteFree(int freeNo) {
ServiceResult result = null;
int status = freeDao.deleteFree(freeNo);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import kr.or.ddit.vo.FreeVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
public int updateFree(FreeVO freeVO);
public int deleteFree(int freeNo);
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
@Override
public int updateFree(FreeVO freeVO) {
return sqlSession.update("Free.updateFree", freeVO);
}
@Override
public int deleteFree(int freeNo) {
return sqlSession.delete("Free.deleteFree", freeNo);
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
<update id="updateFree" parameterType="freeVO">
update free
set
free_title = #{freeTitle},
free_content = #{freeContent},
free_date = sysdate
where free_no = #{freeNo}
</update>
<delete id="deleteFree" parameterType="int">
delete from free
where free_no = #{freeNo}
</delete>
</mapper>
- http://localhost/free/detail.do?freeNo=7
[FreeRetreiveController.java]
package kr.or.ddit.free.web;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
@Controller
@RequestMapping("/free")
public class FreeRetreiveController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/list.do", method = RequestMethod.GET)
public String freeList(Model model) {
List<FreeVO> freeList = freeService.selectFreeList();
model.addAttribute("freeList", freeList);
return "free/list";
}
@RequestMapping(value = "/detail.do", method = RequestMethod.GET)
public String freeDetail(int freeNo, Model model) {
FreeVO freeVO = freeService.selectFree(freeNo);
model.addAttribute("free", freeVO);
return "free/view";
}
}
[IFreeService.java]
package kr.or.ddit.free.service;
import java.util.List;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
public ServiceResult updateFree(FreeVO freeVO);
public ServiceResult deleteFree(int freeNo);
public List<FreeVO> selectFreeList();
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
@Override
public ServiceResult updateFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.updateFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public ServiceResult deleteFree(int freeNo) {
ServiceResult result = null;
int status = freeDao.deleteFree(freeNo);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public List<FreeVO> selectFreeList() {
return freeDao.selectFreeList();
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import java.util.List;
import kr.or.ddit.vo.FreeVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
public int updateFree(FreeVO freeVO);
public int deleteFree(int freeNo);
public List<FreeVO> selectFreeList();
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import java.util.List;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
@Override
public int updateFree(FreeVO freeVO) {
return sqlSession.update("Free.updateFree", freeVO);
}
@Override
public int deleteFree(int freeNo) {
return sqlSession.delete("Free.deleteFree", freeNo);
}
@Override
public List<FreeVO> selectFreeList() {
return sqlSession.selectList("Free.selectFreeList");
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
<update id="updateFree" parameterType="freeVO">
update free
set
free_title = #{freeTitle},
free_content = #{freeContent},
free_date = sysdate
where free_no = #{freeNo}
</update>
<delete id="deleteFree" parameterType="int">
delete from free
where free_no = #{freeNo}
</delete>
<select id="selectFreeList" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
</select>
</mapper>
[list.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="${pageContext.request.contextPath}/resources/plugins/jquery/jquery.min.js"></script>
<title>자유게시판</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"/>
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"/>
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div
class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-header">
<div class="card-tools">
</div>
<h3 class="card-title">자유게시판</h3>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 0건</span>
</div>
</div>
<div class="card-body mt-3">
<div align="right">
<form class="input-group input-group-sm" method="post" id="searchForm" style="width: 440px;">
<select class="form-control" name="searchType">
<option value="title">제목</option>
<option value="writer">작성자</option>
</select>
<input type="text" name="searchWord" class="form-control float-right" value="" placeholder="Search">
<div class="input-group-append">
<button type="submit" class="btn btn-default">
<i class="fas fa-search"></i>검색
</button>
</div>
</form>
</div>
<div class="mt-2">
<table class="table">
<thead class="table-dark">
<tr>
<th style="width: 6%">#</th>
<th style="width: px">제목</th>
<th style="width: 12%">작성자</th>
<th style="width: 12%">작성일</th>
<th style="width: 10%">조회수</th>
</tr>
</thead>
<tbody>
<c:choose>
<c:when test="${empty freeList }">
<tr>
<td colspan="5">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${freeList }" var="free">
<tr>
<td>${free.freeNo }</td>
<td>
<a href="/free/detail.do?freeNo=${free.freeNo }">${free.freeTitle }</a>
</td>
<td>${free.freeWriter }</td>
<td>${free.freeDate }</td>
<td>${free.freeHit }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
</table>
</div>
<div align="left">
<a href="/free/form.do" class="btn btn-primary">등록</a>
</div>
</div>
<div class="card-footer clearfix mt-4" id="pagingArea"></div>
</div>
</div>
<div class="col-md-12"><br/><br/><br/></div>
</div>
</div>
</main>
</body>
</html>
- http://localhost/free/list.do
[FreeRetreiveController.java]
package kr.or.ddit.free.web;
import java.util.List;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Controller
@RequestMapping("/free")
public class FreeRetreiveController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/list.do", method = RequestMethod.GET)
public String freeList(
@RequestParam(name="page", required = false, defaultValue = "1") int currentPage,
@RequestParam(required = false, defaultValue = "title") String searchType,
@RequestParam(required = false) String searchWord,
Model model) {
PaginationInfoVO<FreeVO> pagingVO = new PaginationInfoVO<FreeVO>();
// 검색 키워드가 있으면 검색을 한 것으로 기준을 잡는다.
if(StringUtils.isNotBlank(searchWord)) {
pagingVO.setSearchType(searchType);
pagingVO.setSearchWord(searchWord);
model.addAttribute("searchType", searchType);
model.addAttribute("searchWord", searchWord);
}
pagingVO.setCurrentPage(currentPage);
int totalRecord = freeService.selectFreeCount(pagingVO);
pagingVO.setTotalRecord(totalRecord);
List<FreeVO> dataList = freeService.selectFreeList(pagingVO);
pagingVO.setDataList(dataList);
model.addAttribute("pagingVO", pagingVO);
return "free/list";
}
@RequestMapping(value = "/detail.do", method = RequestMethod.GET)
public String freeDetail(int freeNo, Model model) {
FreeVO freeVO = freeService.selectFree(freeNo);
model.addAttribute("free", freeVO);
return "free/view";
}
}
[IFreeService.java]
package kr.or.ddit.free.service;
import java.util.List;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
public ServiceResult updateFree(FreeVO freeVO);
public ServiceResult deleteFree(int freeNo);
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO);
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
@Override
public ServiceResult updateFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.updateFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public ServiceResult deleteFree(int freeNo) {
ServiceResult result = null;
int status = freeDao.deleteFree(freeNo);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO) {
return freeDao.selectFreeCount(pagingVO);
}
@Override
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO) {
return freeDao.selectFreeList(pagingVO);
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import java.util.List;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
public int updateFree(FreeVO freeVO);
public int deleteFree(int freeNo);
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO);
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import java.util.List;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
@Override
public int updateFree(FreeVO freeVO) {
return sqlSession.update("Free.updateFree", freeVO);
}
@Override
public int deleteFree(int freeNo) {
return sqlSession.delete("Free.deleteFree", freeNo);
}
@Override
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO) {
return sqlSession.selectOne("Free.selectFreeCount", pagingVO);
}
@Override
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO) {
return sqlSession.selectList("Free.selectFreeList", pagingVO);
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<sql id="freeSearch">
<if test="searchType != null and searchType == 'title'">
and (free_title like '%' || #{searchWord} || '%')
</if>
<if test="searchType != null and searchType == 'writer'">
and (free_writer like '%' || #{searchWord} || '%')
</if>
</sql>
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
<update id="updateFree" parameterType="freeVO">
update free
set
free_title = #{freeTitle},
free_content = #{freeContent},
free_date = sysdate
where free_no = #{freeNo}
</update>
<delete id="deleteFree" parameterType="int">
delete from free
where free_no = #{freeNo}
</delete>
<select id="selectFreeCount" parameterType="pagingVO" resultType="int">
select count(free_no) from free
where 1=1
<include refid="freeSearch" />
</select>
<select id="selectFreeList" parameterType="pagingVO" resultType="freeVO">
select b.*
from (
select
a.*, row_number() over (order by a.free_no desc) rnum
from (
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where 1=1
<include refid="freeSearch" />
order by free_no desc
) a
) b
<![CDATA[
where b.rnum >= #{startRow} and b.rnum <= #{endRow}
]]>
</select>
</mapper>
insert into free values (seq_free.nextval, '제목11', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목12', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목13', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목14', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목15', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목16', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목17', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목18', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목19', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목21', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목22', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목23', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목24', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목25', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목26', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목27', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목28', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목29', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목30', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목31', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목32', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목33', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목34', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목35', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목36', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목37', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목38', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목39', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목40', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목41', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목42', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목43', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목44', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목45', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목46', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목47', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목48', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목49', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목50', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목51', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목52', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목53', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목54', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목55', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목56', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목57', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목58', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목59', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목60', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목61', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목62', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목63', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목64', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목65', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목66', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목67', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목68', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목69', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목70', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목71', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목72', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목73', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목74', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목75', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목76', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목77', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목78', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목79', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목80', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목11', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목12', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목13', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목14', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목15', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목16', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목17', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목18', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목19', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목21', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목22', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목23', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목24', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목25', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목26', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목27', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목28', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목29', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목30', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목31', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목32', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목33', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목34', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목35', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목36', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목37', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목38', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목39', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목40', '내용', 'a002', sysdate, 0);
insert into free values (seq_free.nextval, '제목41', '내용', 'a003', sysdate, 0);
insert into free values (seq_free.nextval, '제목42', '내용', 'a003', sysdate, 0);
insert into free values (seq_free.nextval, '제목43', '내용', 'a003', sysdate, 0);
insert into free values (seq_free.nextval, '제목44', '내용', 'a003', sysdate, 0);
insert into free values (seq_free.nextval, '제목45', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목46', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목47', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목48', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목49', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목50', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목51', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목52', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목53', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목54', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목55', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목56', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목57', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목58', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목59', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목60', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목61', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목62', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목63', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목64', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목65', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목66', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목67', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목68', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목69', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목70', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목71', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목72', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목73', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목74', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목75', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목76', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목77', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목78', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목79', '내용', 'b001', sysdate, 0);
insert into free values (seq_free.nextval, '제목80', '내용', 'b001', sysdate, 0);
[list.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<title>자유게시판</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"/>
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"/>
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h4 class="display-4 fw-normal">자유게시판</h4>
<p class="lead fw-normal">자유게시판 CRUD를 작성해주세요.</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div
class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="">
<div class="card-header">
<div class="card-tools">
</div>
<h3 class="card-title">자유게시판</h3>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 ${pagingVO.totalRecord }건</span>
</div>
</div>
<div class="card-body mt-3">
<div align="right">
<form class="input-group input-group-sm" method="post" id="searchForm" style="width: 440px;">
<input type="hidden" name="page" id="page" />
<select class="form-control" name="searchType">
<option value="title">제목</option>
<option value="writer">작성자</option>
</select>
<input type="text" name="searchWord" class="form-control float-right" value="" placeholder="Search">
<div class="input-group-append">
<button type="submit" class="btn btn-default">
<i class="fas fa-search"></i>검색
</button>
</div>
</form>
</div>
<div class="mt-2">
<table class="table">
<thead class="table-dark">
<tr>
<th style="width: 6%">#</th>
<th style="width: px">제목</th>
<th style="width: 12%">작성자</th>
<th style="width: 12%">작성일</th>
<th style="width: 10%">조회수</th>
</tr>
</thead>
<tbody>
<c:set value="${pagingVO.dataList }" var="freeList" />
<c:choose>
<c:when test="${empty freeList }">
<tr>
<td colspan="5">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${freeList }" var="free">
<tr>
<td>${free.freeNo }</td>
<td>
<a href="/free/detail.do?freeNo=${free.freeNo }">${free.freeTitle }</a>
</td>
<td>${free.freeWriter }</td>
<td>${free.freeDate }</td>
<td>${free.freeHit }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
</table>
</div>
<div align="left">
<a href="/free/form.do" class="btn btn-primary">등록</a>
</div>
</div>
<div class="card-footer clearfix mt-4" id="pagingArea">
${pagingVO.pagingHTML }
</div>
</div>
</div>
<div class="col-md-12"><br/><br/><br/></div>
</div>
</div>
</main>
</body>
<script type="text/javascript">
$(function(){
var pagingArea = $("#pagingArea");
var searchForm = $("#searchForm");
pagingArea.on("click", "a", function(event){
event.preventDefault();
var pageNo = $(this).data("page");
searchForm.find("#page").val(pageNo);
searchForm.submit();
});
});
</script>
</html>
[FreeRetreiveController.java]
@Controller
@RequestMapping("/free")
public class FreeRetreiveController {
@Inject
private IFreeService freeService;
@RequestMapping(value = "/list.do")
public String freeList(
- http://localhost/free/list.do
[MainController.java]
package kr.or.ddit.main.web;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.free.service.IFreeService;
import kr.or.ddit.vo.BoardVO;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Controller
public class MainController {
@Inject
private IBoardService boardService;
@Inject
private IFreeService freeService;
@RequestMapping(value = { "/", "/main.do" }, method = RequestMethod.GET)
public String main(Model model) {
PaginationInfoVO<BoardVO> boardPagingVO = new PaginationInfoVO<BoardVO>();
List<BoardVO> boardList5 = boardService.selectBoardList_();
int boardTotalRecord = boardService.selectBoardCount(boardPagingVO);
model.addAttribute("boardList5", boardList5);
model.addAttribute("boardTotalRecord", boardTotalRecord);
PaginationInfoVO<FreeVO> freePagingVO = new PaginationInfoVO<FreeVO>();
List<FreeVO> freeList5 = freeService.selectFreeList_();
int freeTotalRecord = freeService.selectFreeCount(freePagingVO);
model.addAttribute("freeList5", freeList5);
model.addAttribute("freeTotalRecord", freeTotalRecord);
return "main";
}
}
[IFreeService.java]
package kr.or.ddit.free.service;
import java.util.List;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
public interface IFreeService {
public ServiceResult insertFree(FreeVO freeVO);
public FreeVO selectFree(int freeNo);
public ServiceResult updateFree(FreeVO freeVO);
public ServiceResult deleteFree(int freeNo);
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList_();
}
[FreeServiceImpl.java]
package kr.or.ddit.free.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.free.dao.IFreeDAO;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Service
public class FreeServiceImpl implements IFreeService {
@Inject
private IFreeDAO freeDao;
@Override
public ServiceResult insertFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.insertFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public FreeVO selectFree(int freeNo) {
// 조회수 증가
freeDao.incrementHit(freeNo);
return freeDao.selectFree(freeNo);
}
@Override
public ServiceResult updateFree(FreeVO freeVO) {
ServiceResult result = null;
int status = freeDao.updateFree(freeVO);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public ServiceResult deleteFree(int freeNo) {
ServiceResult result = null;
int status = freeDao.deleteFree(freeNo);
if(status > 0) { // 성공
result = ServiceResult.OK;
}else { // 실패
result = ServiceResult.FAILED;
}
return result;
}
@Override
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO) {
return freeDao.selectFreeCount(pagingVO);
}
@Override
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO) {
return freeDao.selectFreeList(pagingVO);
}
@Override
public List<FreeVO> selectFreeList_() {
return freeDao.selectFreeList_();
}
}
[IFreeDAO.java]
package kr.or.ddit.free.dao;
import java.util.List;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
public interface IFreeDAO {
public int insertFree(FreeVO freeVO);
public void incrementHit(int freeNo);
public FreeVO selectFree(int freeNo);
public int updateFree(FreeVO freeVO);
public int deleteFree(int freeNo);
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO);
public List<FreeVO> selectFreeList_();
}
[FreeDAOImpl.java]
package kr.or.ddit.free.dao;
import java.util.List;
import javax.inject.Inject;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.FreeVO;
import kr.or.ddit.vo.PaginationInfoVO;
@Repository
public class FreeDAOImpl implements IFreeDAO {
@Inject
private SqlSessionTemplate sqlSession;
@Override
public int insertFree(FreeVO freeVO) {
return sqlSession.insert("Free.insertFree", freeVO);
}
@Override
public void incrementHit(int freeNo) {
sqlSession.update("Free.incrementHit", freeNo);
}
@Override
public FreeVO selectFree(int freeNo) {
return sqlSession.selectOne("Free.selectFree", freeNo);
}
@Override
public int updateFree(FreeVO freeVO) {
return sqlSession.update("Free.updateFree", freeVO);
}
@Override
public int deleteFree(int freeNo) {
return sqlSession.delete("Free.deleteFree", freeNo);
}
@Override
public int selectFreeCount(PaginationInfoVO<FreeVO> pagingVO) {
return sqlSession.selectOne("Free.selectFreeCount", pagingVO);
}
@Override
public List<FreeVO> selectFreeList(PaginationInfoVO<FreeVO> pagingVO) {
return sqlSession.selectList("Free.selectFreeList", pagingVO);
}
@Override
public List<FreeVO> selectFreeList_() {
return sqlSession.selectList("Free.selectFreeList_");
}
}
[free_SQL.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Free">
<sql id="freeSearch">
<if test="searchType != null and searchType == 'title'">
and (free_title like '%' || #{searchWord} || '%')
</if>
<if test="searchType != null and searchType == 'writer'">
and (free_writer like '%' || #{searchWord} || '%')
</if>
</sql>
<insert id="insertFree" parameterType="freeVO" useGeneratedKeys="true">
<selectKey keyProperty="freeNo" resultType="int" order="BEFORE">
select seq_free.nextval from dual
</selectKey>
insert into free(
free_no, free_title, free_content, free_writer, free_date
)values(
#{freeNo}, #{freeTitle}, #{freeContent}, #{freeWriter}, sysdate
)
</insert>
<update id="incrementHit" parameterType="int">
update free
set
free_hit = free_hit + 1
where free_no = #{freeNo}
</update>
<select id="selectFree" parameterType="int" resultType="freeVO">
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where free_no = #{freeNo}
</select>
<update id="updateFree" parameterType="freeVO">
update free
set
free_title = #{freeTitle},
free_content = #{freeContent},
free_date = sysdate
where free_no = #{freeNo}
</update>
<delete id="deleteFree" parameterType="int">
delete from free
where free_no = #{freeNo}
</delete>
<select id="selectFreeCount" parameterType="pagingVO" resultType="int">
select count(free_no) from free
where 1=1
<include refid="freeSearch" />
</select>
<select id="selectFreeList" parameterType="pagingVO" resultType="freeVO">
select b.*
from (
select
a.*, row_number() over (order by a.free_no desc) rnum
from (
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
where 1=1
<include refid="freeSearch" />
order by free_no desc
) a
) b
<![CDATA[
where b.rnum >= #{startRow} and b.rnum <= #{endRow}
]]>
</select>
<select id="selectFreeList_" resultType="freeVO">
<![CDATA[
select *
from (
select
free_no, free_title, free_content, free_writer, free_date, free_hit
from free
order by free_no desc
)
where rownum <= 5
]]>
</select>
</mapper>
[main.jsp]
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page import="java.util.*"%>
<html>
<head>
<link href="${pageContext.request.contextPath }/resources/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/headers.css">
<title>메인화면</title>
</head>
<style>
.bi {
vertical-align: -.125em;
fill: currentColor;
}
</style>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bootstrap" viewBox="0 0 118 94">
<title>Bootstrap</title>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z"></path>
</symbol>
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z" />
</symbol>
<symbol id="grid" viewBox="0 0 16 16">
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</symbol>
</svg>
<main>
<header>
<div class="px-3 py-2 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center my-2 my-lg-0 me-lg-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul class="nav col-12 col-lg-auto my-2 justify-content-center my-md-0 text-small">
<li>
<a href="/main.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#home" />
</svg> Home
</a>
</li>
<li>
<a href="/board/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 일반게시판
</a>
</li>
<li>
<a href="/notice/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 공지사항게시판
</a>
</li>
<li>
<a href="/free/list.do" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#grid" />
</svg> 자유게시판
</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div class="position-relative overflow-hidden p-3 p-md-8 m-md-8 text-center bg-white">
<div class="col-md-8 p-lg-8 mx-auto my-5">
<h1 class="display-4 fw-normal">게시판 작성 연습</h1>
<p class="lead fw-normal">Spring framework를 이용한 게시판 CRUD Example</p>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div class="container">
<div class="row">
<div class="col-md-6">
<div align="left">
<h5>일반 게시판</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 ${boardTotalRecord }건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<c:choose>
<c:when test="${empty boardList5 }">
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${boardList5 }" var="board">
<tr>
<td>${board.boNo }</td>
<td>
<a href="/board/detail.do?boNo=${board.boNo }">${board.boTitle }</a>
</td>
<td>${board.boDate }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
</div>
</form>
<a href="/board/list.do" class="btn btn-outline-primary">«더보기</a>
</div>
<div class="col-md-6">
<div align="left">
<h5>공지사항</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 ${freeTotalRecord }건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</form>
<a href="" class="btn btn-outline-primary">«더보기</a>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6">
<div align="left">
<h5>자유 게시판</h5>
</div>
<div align="right">
<span class="badge bg-dark-subtle border border-dark-subtle text-dark-emphasis rounded-pill">전체 0건</span>
</div>
<form action="" method="post">
<div style="padding-top: 50px">
<table class="table">
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일</th>
</tr>
<c:choose>
<c:when test="${empty freeList5 }">
<tr>
<td colspan="3">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${freeList5 }" var="free">
<tr>
<td>${free.freeNo }</td>
<td>
<a href="/free/detail.do?freeNo=${free.freeNo }">${free.freeTitle }</a>
</td>
<td>${free.freeDate }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
</div>
</form>
<a href="/free/list.do" class="btn btn-outline-primary">«더보기</a>
</div>
<div class="col-md-6"></div>
</div>
<br />
</div>
</main>
</body>
</html>
- http://localhost/main.do
'대덕인재개발원 > 대덕인재개발원_웹기반 애플리케이션' 카테고리의 다른 글
231122_SPRING 2 (1-1) (0) | 2023.11.22 |
---|---|
231121_SPRING 1 (5-3) - 공지사항 게시판 과제 (0) | 2023.11.21 |
231121_SPRING 1 (5-1) (1) | 2023.11.21 |
231120_SPRING 1 (4) (0) | 2023.11.20 |
231117_SPRING 1 (3) (0) | 2023.11.17 |