공지사항목록조회
mybatis_config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0/EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- vo 별칭 지정 -->
<typeAliases>
<!-- 별칭 지정시 반드시 클래스부터 선언 후 별칭 지정! -->
<typeAlias type="edu.springboard.vo.UserVO" alias="userVO"/>
<typeAlias type="edu.springboard.vo.NoticeVO" alias="noticeVO" />
</typeAliases>
</configuration>
NoticeVO
package edu.springboard.vo;
public class NoticeVO extends UserVO {
private String nno;
private String title;
private String content;
private String rdate;
private String hit;
private String state;
private String topYn; //DB의 컬럼은 top_yn이지만 카멜기법을 사용해 topYn로 사용해도 적용된다
private String filename;
public String getNno() { return nno; }
public String getTitle() { return title; }
public String getContent() { return content; }
public String getRdate() { return rdate; }
public String getHit() { return hit; }
public String getState() { return state; }
public String getTopYn() { return topYn; }
public String getFilename() { return filename; }
public void setNno(String nno) { this.nno = nno; }
public void setTitle(String title) { this.title = title; }
public void setContent(String content) { this.content = content; }
public void setRdate(String rdate) { this.rdate = rdate; }
public void setHit(String hit) { this.hit = hit; }
public void setState(String state) { this.state = state; }
public void setTopYn(String topYn) { this.topYn = topYn; }
public void setFilename(String filename) { this.filename = filename; }
}
NoticeMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.springboard.mapper.noticeMapper">
<select id="selectAll" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
</select>
<select id="selectOne" parameterType="String" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
WHERE nno=#{nno}
</select>
</mapper>
NoticeController
package edu.springboard.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import edu.springboard.service.NoticeService;
import edu.springboard.vo.NoticeVO;
@Controller
public class NoticeController {
@Autowired
public NoticeService noticeService;
@RequestMapping(value="/notice/list.do")
public String noticeList(Model model) {
//비지니스 로직 : DB에 있는 전체 회원 목록 데이터 가져오기
List<NoticeVO> list = noticeService.selectAll();
//모델 객체 사용하여 조회 데이터 화면으로 포워딩
model.addAttribute("list", list);
return "notice/list";
}
}
NoticeService
package edu.springboard.service;
import java.util.List;
import edu.springboard.vo.NoticeVO;
public interface NoticeService {
public List<NoticeVO> selectAll();
}
NoticeServiceImpl
package edu.springboard.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import edu.springboard.dao.NoticeDAO;
import edu.springboard.vo.NoticeVO;
@Service
public class NoticeServiceImpl implements NoticeService {
@Autowired
public NoticeDAO noticeDAO;
@Override
public List<NoticeVO> selectAll() {
return noticeDAO.selectAll();
}
}
NoticeDAO
package edu.springboard.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import edu.springboard.vo.NoticeVO;
@Repository
public class NoticeDAO {
@Autowired
public SqlSession sqlSession;
public List<NoticeVO> selectAll() {
return sqlSession.selectList("edu.springboard.mapper.noticeMapper.selectAll");
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항목록조회</title>
</head>
<body>
<a href="<%= request.getContextPath() %>">home으로 돌아가기</a>
<h2>공지사항목록조회</h2><hr>
<table border="0">
<tr>
<th style="width:60px;">글번호</th>
<th style="width:220px;">제목</th>
<th style="width:100px;">작성자</th>
<th style="width:160px;">등록일</th>
</tr>
<c:forEach items="${list}" var="list">
<tr>
<td>${list.nno}</td>
<td>
<a href="view.do?uno=${list.nno}">${list.title}</a>
</td>
<td>${list.uid}</td>
<td>${list.rdate}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
공지글검색
noticeMapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="edu.springboard.mapper.noticeMapper">
<select id="selectAll" parameterType="searchVO" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
<if test="searchType != null and searchType.equals('title')">
WHERE title LIKE concat('%',#{searchValue} ,'%')
</if>
<if test="searchType != null and searchType.equals('id')">
WHERE uid LIKE concat('%',#{searchValue} ,'%')
</if>
</select>
<select id="selectOne" parameterType="String" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
WHERE nno=#{nno}
</select>
</mapper>
SearchVO
package edu.springboard.vo;
public class SearchVO {
private String searchType;
private String searchValue;
public String getSearchType() { return searchType; }
public String getSearchValue() { return searchValue; }
public void setSearchType(String searchType) { this.searchType = searchType; }
public void setSearchValue(String searchValue) { this.searchValue = searchValue; }
}
mybatis_config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0/EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- vo 별칭 지정 -->
<typeAliases>
<!-- 별칭 지정시 반드시 클래스부터 선언 후 별칭 지정! -->
<typeAlias type="edu.springboard.vo.UserVO" alias="userVO"/>
<typeAlias type="edu.springboard.vo.NoticeVO" alias="noticeVO" />
<typeAlias type="edu.springboard.vo.SearchVO" alias="searchVO" />
</typeAliases>
</configuration>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항목록조회</title>
<link rel="stylesheet" type="text/css" href="<%= request.getContextPath() %>/resources/css/spring.css" />
</head>
<body>
<a href="<%= request.getContextPath() %>"><button class="sBtn">home</button></a>
<h2>공지사항목록조회</h2><hr>
<form action="list.do" method="get">
<select name="searchType">
<option value="title">제목</option>
<option value="id">작성자(id)</option>
</select>
<input type="text" name="searchValue">
<button style="width:80px; height:30px;">검색</button>
</form>
<table border="0" style="text-align:center;">
<tr>
<th style="width:60px;">글번호</th>
<th style="width:220px;">제목</th>
<th style="width:100px;">작성자</th>
<th style="width:160px;">등록일</th>
</tr>
<c:forEach items="${list}" var="list">
<tr>
<td>${list.nno}</td>
<td>
<a href="view.do?nno=${list.nno}">${list.title}</a>
</td>
<td>${list.uid}</td>
<td>${list.rdate}</td>
</tr>
</c:forEach>
</table>
<!--
메인페이지에서 공지사항 목록 이동 링크 클릭시 현재 list.jsp가 포워드 될 수 있도록 기능을 구현합니다.
이때 테이블은 notice_board 테이블을 사용합니다
작성자는 게시글 등록자 id를 출력합니다
-->
</body>
</html>
NoticeDAO
package edu.springboard.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import edu.springboard.vo.NoticeVO;
import edu.springboard.vo.SearchVO;
@Repository
public class NoticeDAO {
@Autowired
public SqlSession sqlSession;
public List<NoticeVO> selectAll(SearchVO searchVO) {
return sqlSession.selectList("edu.springboard.mapper.noticeMapper.selectAll",searchVO);
}
public NoticeVO selectOne(String nno) {
return sqlSession.selectOne("edu.springboard.mapper.noticeMapper.selectOne",nno);
}
}
NoticeServiceImpl
package edu.springboard.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import edu.springboard.dao.NoticeDAO;
import edu.springboard.vo.NoticeVO;
import edu.springboard.vo.SearchVO;
@Service
public class NoticeServiceImpl implements NoticeService {
@Autowired
public NoticeDAO noticeDAO;
@Override
public List<NoticeVO> selectAll(SearchVO searchVO) {
return noticeDAO.selectAll(searchVO);
}
@Override
public NoticeVO selectOne(String nno) {
return noticeDAO.selectOne(nno);
}
}
NoticeService
package edu.springboard.service;
import java.util.List;
import edu.springboard.vo.NoticeVO;
import edu.springboard.vo.SearchVO;
import edu.springboard.vo.UserVO;
public interface NoticeService {
public List<NoticeVO> selectAll(SearchVO searchVO);
public NoticeVO selectOne(String nno);
}
NoticeController
package edu.springboard.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import edu.springboard.service.NoticeService;
import edu.springboard.vo.NoticeVO;
import edu.springboard.vo.SearchVO;
import edu.springboard.vo.UserVO;
@Controller
public class NoticeController {
@Autowired
public NoticeService noticeService;
@RequestMapping(value="/board/list.do")
public String noticeList(Model model,SearchVO searchVO) {
//비지니스 로직 : DB에 있는 전체 회원 목록 데이터 가져오기
List<NoticeVO> list = noticeService.selectAll(searchVO);
//모델 객체 사용하여 조회 데이터 화면으로 포워딩
model.addAttribute("list", list);
return "notice/list";
}
@RequestMapping(value="/board/view.do")
public String view(String nno, Model model) {
NoticeVO notice = noticeService.selectOne(nno);
if(notice != null) {
System.out.println("조회완료");
model.addAttribute("notice",notice);
return "notice/view";
}else {
System.out.println("조회실패");
return "redirect:/";
}
}
}
공지글페이징
PagingUtil
package edu.springboard.util;
public class PagingUtil { //(o) : 반드시 필요
// o : 외부에서 받아올 연산에 필요한 데이터를 담을 필드
// o 없음 : o 데이터들을 활용하여 연산된 결과를 담을 필드
private int nowPage; //현재페이지번호(o)
private int startPage; //사작페이지번호
private int endPage; //종료페이지번호
private int total; //전체 게시글 수(o)
private int perPage; //한 페이지당 게시글 갯수(o)
private int lastPage; //최종 페이지 번호
private int start; //시작 게시글 번호
private int end; //종료 게시글 번호
private int cntPage=5;//한 페이지에서 보여지는 페이징 번호 수(o)
public PagingUtil() {}
public PagingUtil(int nowPage,int total, int perPage) {
setNowPage(nowPage);
setTotal(total);
setPerPage(perPage);
calcStartEnd(nowPage,perPage); //시작번호 종료번호 연산 기능 호출
calcLastPage(total, perPage);
calcStartEndPage(nowPage,cntPage);
}
public void calcStartEnd(int nowPage,int perPage) {
int end = nowPage * perPage; //게시글 종료번호(oracle에서 사용)
/*
현재 페이지 : 1 / 게시글 노출 갯수 : 5
종료번호 : 1*5 -> 5
시작번호 : 종료번호 - 게시글 노출 갯수(5-5 = 0)
--> limit 0,5
현재 페이지 : 2 / 게시글 노출 갯수 : 5
종료번호 : 2*5 -> 10
시작번호 : 종료번호 - 게시글 노출 갯수(10-5 = 5)
--> limit 5,5
*/
int start = end - perPage; //게시글 시작번호.(oracle에서는 +1을 해야함)
setEnd(end);
setStart(start);
}
//총 11개 한페이지당 10개씩 페이지 최종 번호 : 2
public void calcLastPage(int total, int perPage) {
//전체 게시글에서 페이지당 게시글 수를 나눈 실수를 올림처리 한 값을 반환
int lastPage = (int)Math.ceil((double)total/perPage);
setLastPage(lastPage);
}
//현재페이지 : 3 / 시작페이지 번호 : 1 / 종료페이지 번호 : 10
public void calcStartEndPage(int nowPage,int cntPage) {
//현재 페이지의 10의 자리를 구해와 +1을 한 후 페이지당 노출 페이지 갯수 곱하기
int endPage = (int)Math.ceil((double)nowPage / cntPage) * cntPage;
int startPage = endPage - cntPage + 1;
if(endPage > lastPage) {
endPage = lastPage;
}
setEndPage(endPage);
setStartPage(startPage);
}
public int getNowPage() { return nowPage; }
public int getStartPage() { return startPage; }
public int getEndPage() { return endPage; }
public int getTotal() { return total; }
public int getPerPage() { return perPage; }
public int getLastPage() { return lastPage; }
public int getStart() { return start; }
public int getEnd() { return end; }
public int getCntPage() { return cntPage; }
public void setNowPage(int nowPage) { this.nowPage = nowPage; }
public void setStartPage(int startPage) { this.startPage = startPage; }
public void setEndPage(int endPage) { this.endPage = endPage; }
public void setTotal(int total) { this.total = total; }
public void setPerPage(int perPage) { this.perPage = perPage; }
public void setLastPage(int lastPage) { this.lastPage = lastPage; }
public void setStart(int start) { this.start = start; }
public void setEnd(int end) { this.end = end; }
public void setCntPage(int cntPage) { this.cntPage = cntPage; }
}
SearchVO
package edu.springboard.vo;
import edu.springboard.util.PagingUtil;
public class SearchVO extends PagingUtil {
private String searchType;
private String searchValue;
public String getSearchType() { return searchType; }
public String getSearchValue() { return searchValue; }
public void setSearchType(String searchType) { this.searchType = searchType; }
public void setSearchValue(String searchValue) { this.searchValue = searchValue; }
}
noticeMapper
<select id="selectAll" parameterType="searchVO" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
WHERE state='E'
<if test="searchType != null and searchType.equals('title')">
AND title LIKE concat('%',#{searchValue} ,'%')
</if>
<if test="searchType != null and searchType.equals('id')">
AND uid LIKE concat('%',#{searchValue} ,'%')
</if>
order by nno desc
limit #{start},#{perPage}
</select>
NoticeDAO
public int selectCount(SearchVO searchVO) {
return sqlSession.selectOne("edu.springboard.mapper.noticeMapper.selectCount",searchVO);
}
NoticeServiceImpl
@Override
public int selectCount(SearchVO searchVO) {
return noticeDAO.selectCount(searchVO);
}
NoticeService
public int selectCount(SearchVO searchVO);
NoticeController
@RequestMapping(value="/board/list.do")
public String noticeList(Model model,SearchVO searchVO
, @RequestParam(value="nowPage", required = false, defaultValue = "1") int nowPage) {
//@RequestParam의 value는 넘어오는 값을 그 이름으로
//required false를 하면 필수가 아니고 값이 넘어오지 않을 경우 defaultValue로 적용된다
System.out.println("nowPage:" + nowPage);
//DB에서 공지사항의 전체 게시글 갯수를 조회
int total = noticeService.selectCount(searchVO);
System.out.println("공지글 갯수:" + total);
//int nowPage,int total, int perPage
PagingUtil paging = new PagingUtil(nowPage,total,5);
searchVO.setStart(paging.getStart());
searchVO.setPerPage(paging.getPerPage());
System.out.println("paging.getStart():"+ paging.getStart());
System.out.println("paging.getPerPage():"+ paging.getPerPage());
//비지니스 로직 : DB에 있는 전체 회원 목록 데이터 가져오기
List<NoticeVO> list = noticeService.selectAll(searchVO);
//모델 객체 사용하여 조회 데이터 화면으로 포워딩
model.addAttribute("list", list);
return "notice/list";
}
@RequestParam
value (또는 name)
- 클라이언트가 요청 시 전달하는 쿼리 파라미터의 이름을 지정합니다.
- 지정된 이름의 값이 요청에 포함되어야만 매핑이 이루어집니다.
- 예를 들어, /board/list.do?nowPage=3와 같은 요청이 들어오면, nowPage 파라미터의 값 3이 int nowPage 변수에 저장됩니다.
required
- 기본값: true
- true: 해당 파라미터가 요청에 반드시 포함되어야 함. 포함되지 않으면 예외 발생.
- false: 요청에 파라미터가 없어도 허용.
defaultValue
- 파라미터가 요청에 포함되지 않거나 빈 값일 경우 사용할 기본값을 지정합니다.
- required = false와 함께 사용하는 것이 일반적입니다.
- 만약 nowPage가 요청에 포함되지 않은 경우(/board/list.do), defaultValue에 지정된 기본값인 1이 nowPage에 할당됩니다.
- required = false로 설정했기 때문에, nowPage가 쿼리 파라미터로 전달되지 않아도 예외가 발생하지 않습니다.
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항목록조회</title>
<link rel="stylesheet" type="text/css" href="<%= request.getContextPath() %>/resources/css/spring.css" />
</head>
<body>
<a href="<%= request.getContextPath() %>"><button class="sBtn">home</button></a>
<h2>공지사항목록조회</h2><hr>
<form action="list.do" method="get">
<select name="searchType">
<option value="title"
<c:if test="${param.searchType eq 'title'}">
selected
</c:if>
>제목</option>
<option value="id"
<c:if test="${param.searchType eq 'id'}">
selected
</c:if>
>작성자(id)</option>
</select>
<input type="text" name="searchValue" value="${param.searchValue}">
<button style="width:80px; height:30px;">검색</button>
</form>
<table border="0" style="text-align:center; width:700px;">
<tr>
<th style="width:60px; text-align:center; ">글번호</th>
<th style="width:220px; text-align:center; ">제목</th>
<th style="width:100px; text-align:center; ">작성자</th>
<th style="width:160px; text-align:center; ">등록일</th>
</tr>
<c:forEach items="${list}" var="list">
<tr>
<td>${list.nno}</td>
<td>
<a href="view.do?nno=${list.nno}">${list.title}</a>
</td>
<td>${list.uid}</td>
<td>${list.rdate}</td>
</tr>
</c:forEach>
</table>
<!-- 페이징 영역 -->
<div style="text-align: center; width:700px;">
<!-- 이전페이지로 이동 -->
<c:if test="${paging.startPage > 1 }">
<a href="list.do?nowPage=${paging.startPage-1}&searchValue=${param.searchValue}&searchType=${param.searchType}"><</a>
</c:if>
<!-- 페이지번호 -->
<c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="cnt">
<c:if test="${paging.nowPage eq cnt}">
<b style="color:#FF5722;">${cnt}</b>
</c:if>
<c:if test="${paging.nowPage ne cnt}">
<a href="list.do?nowPage=${cnt}&searchValue=${param.searchValue}&searchType=${param.searchType}">${cnt}</a>
</c:if>
</c:forEach>
<!-- 다음페이지로 이동 -->
<c:if test="${paging.endPage < paging.lastPage}">
<a href="list.do?nowPage=${paging.endPage+1}&searchValue=${param.searchValue}&searchType=${param.searchType}">></a>
</c:if>
</div>
</body>
</html>
회원목록조회페이징
UserController
@RequestMapping(value="/user/list.do")
public String userList(Model model, HttpServletRequest request,SearchVO searchVO
, @RequestParam(value="nowPage", required = false, defaultValue = "1") int nowPage) {
//권한체크 : 로그인된 회원 권한이 관리자인지
HttpSession session = request.getSession();
if(session.getAttribute("loginUser") == null
||
!((UserVO)session.getAttribute("loginUser")).getUauthor().equals("A")) {
return "redirect:/";
}
System.out.println("nowPage:" + nowPage);
int total = userService.selectCount(searchVO);
System.out.println("공지글 갯수:" + total);
PagingUtil paging = new PagingUtil(nowPage,total,3);
searchVO.setStart(paging.getStart());
searchVO.setPerPage(paging.getPerPage());
System.out.println("paging.getStart():"+ paging.getStart());
System.out.println("paging.getPerPage():"+ paging.getPerPage());
//비지니스 로직 : DB에 있는 전체 회원 목록 데이터 가져오기
List<UserVO> userList = userService.selectAll(searchVO);
//모델 객체 사용하여 조회 데이터 화면으로 포워딩
model.addAttribute("userList", userList);
model.addAttribute("paging", paging);
model.addAttribute("total", total);
return "user/list";
}
UserService
package edu.springboard.service;
import java.util.List;
import edu.springboard.vo.SearchVO;
import edu.springboard.vo.UserVO;
public interface UserService {
public int insert(UserVO userVO); //추상메소드
public int update(UserVO userVO); //추상메소드
public UserVO selectbyLogin(UserVO userVO);
public List<UserVO> selectAll(SearchVO searchVO);
public int selectCount(SearchVO searchVO);
public UserVO selectOne(String uno);
}
UserServiceImpl
@Override
public List<UserVO> selectAll(SearchVO searchVO) {
return userDAO.selectAll(searchVO);
}
@Override
public int selectCount(SearchVO searchVO) {
return userDAO.selectCount(searchVO);
}
UserDAO
public List<UserVO> selectAll(SearchVO searchVO) {
return sqlSession.selectList("edu.springboard.mapper.userMapper.selectAll",searchVO);
}
public int selectCount(SearchVO searchVO) {
return sqlSession.selectOne("edu.springboard.mapper.userMapper.selectCount",searchVO);
}
UserMapper.xml
<select id="selectAll" parameterType="searchVO" resultType="userVO">
SELECT * FROM user
<if test="searchType != null and searchType.equals('id')">
WHERE uid LIKE concat('%',#{searchValue} ,'%')
</if>
limit #{start},#{perPage}
</select>
<select id="selectCount" parameterType="searchVO" resultType="int">
SELECT count(*) as total FROM user
<if test="searchType != null and searchType.equals('id')">
WHERE uid LIKE concat('%',#{searchValue} ,'%')
</if>
</select>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원목록조회</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/spring.css" />
</head>
<body>
<a href="<%= request.getContextPath() %>"><button class="sBtn">home</button></a>
<h2>회원목록조회</h2><hr>
<form action="list.do" method="get">
<select name="searchType">
<option value="id"
<c:if test="${param.searchType eq 'id'}">
selected
</c:if>
>아이디</option>
<option value="uname"
<c:if test="${param.searchType eq 'uname'}">
selected
</c:if>
>이름</option>
</select>
<input type="text" name="searchValue" value="${param.searchValue}">
<button style="width:80px; height:30px;">검색</button>
</form>
<table border="0" style="text-align: center; width:550px;">
<tr>
<th style="text-align: center; width:60px;">회원번호</th>
<th style="text-align: center; width:120px;">아이디</th>
<th style="text-align: center; width:120px;">이름</th>
<th style="text-align: center; width:160px;">가입일</th>
</tr>
<c:forEach items="${userList}" var="userList">
<tr>
<td>${userList.uno}</td>
<td>
<a href="view.do?uno=${userList.uno}">${userList.uid}</a>
</td>
<td>${userList.uname}</td>
<td>${userList.rdate}</td>
</tr>
</c:forEach>
</table>
<!-- 페이징 영역 -->
<div style="text-align: center; width:550px;">
<!-- 이전페이지로 이동 -->
<c:if test="${paging.startPage > 1 }">
<a href="list.do?nowPage=${paging.startPage-1}&searchValue=${param.searchValue}&searchType=${param.searchType}"><</a>
</c:if>
<!-- 페이지번호 -->
<c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="cnt">
<c:if test="${paging.nowPage eq cnt}">
<b style="color:#FF5722;">${cnt}</b>
</c:if>
<c:if test="${paging.nowPage ne cnt}">
<a href="list.do?nowPage=${cnt}&searchValue=${param.searchValue}&searchType=${param.searchType}">${cnt}</a>
</c:if>
</c:forEach>
<!-- 다음페이지로 이동 -->
<c:if test="${paging.endPage < paging.lastPage}">
<a href="list.do?nowPage=${paging.endPage+1}&searchValue=${param.searchValue}&searchType=${param.searchType}">></a>
</c:if>
</div>
</body>
</html>
공지글등록 후 조회
noticeMapper
<select id="selectOne" parameterType="int" resultType="noticeVO">
SELECT n.*,uid FROM notice_board n
inner join user u
on n.uno = u.uno
WHERE nno=#{nno}
</select>
<insert id="insert" parameterType="noticeVO">
insert into notice_board(
title,
content,
uno
) values(
#{title},
#{content},
#{uno}
)
<selectKey order="AFTER" resultType="int" keyProperty="nno">
select max(nno) from notice_board
</selectKey>
</insert>
selectKey
order="AFTER"
- 이 속성은 SELECT 키가 실행될 타이밍을 지정합니다.
- AFTER: INSERT 문 실행 후에 키 값을 가져옵니다.
- BEFORE: INSERT 문 실행 전에 키 값을 가져옵니다.
resultType="int"
- 키 값의 반환 타입을 지정합니다. 이 예에서는 반환 타입이 정수형(int)입니다.
keyProperty="nno"
- 키 값을 매핑할 객체의 속성 이름을 지정합니다.
- 반환된 값을 매핑할 객체의 nno 속성에 저장합니다
NoticeDAO
package edu.springboard.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import edu.springboard.vo.NoticeVO;
import edu.springboard.vo.SearchVO;
@Repository
public class NoticeDAO {
@Autowired
public SqlSession sqlSession;
private final String namespace = "edu.springboard.mapper.noticeMapper";
public List<NoticeVO> selectAll(SearchVO searchVO) {
return sqlSession.selectList(namespace+".selectAll",searchVO);
}
public int selectCount(SearchVO searchVO) {
return sqlSession.selectOne(namespace+".selectCount",searchVO);
}
public NoticeVO selectOne(int nno) {
return sqlSession.selectOne(namespace+".selectOne",nno);
}
public int insert(NoticeVO noticeVO) {
return sqlSession.insert(namespace+".insert",noticeVO);
}
public int selectLast() {
return sqlSession.selectOne(namespace+".selectLast");
}
}
NoticeServiceImpl
@Override
public NoticeVO selectOne(int nno) {
return noticeDAO.selectOne(nno);
}
@Override
public int insert(NoticeVO noticeVO) {
return noticeDAO.insert(noticeVO);
}
@Override
public int selectLast() {
return noticeDAO.selectLast();
}
NoticeService
public NoticeVO selectOne(int nno);
public int insert(NoticeVO noticeVO);
public int selectLast();
NoticeController
@RequestMapping(value="/board/view.do")
public String view(int nno, Model model) {
NoticeVO notice = noticeService.selectOne(nno);
if(notice != null) {
System.out.println("조회완료");
model.addAttribute("notice",notice);
return "notice/view";
}else {
System.out.println("조회실패");
return "redirect:/";
}
}
@RequestMapping(value="/board/write.do", method = RequestMethod.POST)
public String write(NoticeVO noticeVO,HttpServletRequest request) {
HttpSession session = request.getSession();
noticeVO.setUno(((UserVO)session.getAttribute("loginUser")).getUno());
int result = noticeService.insert(noticeVO);
if(result > 0) {
System.out.println("글등록완료");
/* int nno = noticeService.selectLast(); */
System.out.println("nno:"+noticeVO.getNno());
return "redirect:view.do?nno="+noticeVO.getNno();
}else {
System.out.println("글등록실패");
return "redirect:write.do";
}
}
NoticeVO
package edu.springboard.vo;
public class NoticeVO extends UserVO {
private int nno;
private String title;
private String content;
private String rdate;
private String hit;
private String state;
private String topYn; //DB의 컬럼은 top_yn이지만 카멜기법을 사용해 topYn로 사용해도 적용된다
private String filename;
public int getNno() { return nno; }
public String getTitle() { return title; }
public String getContent() { return content; }
public String getRdate() { return rdate; }
public String getHit() { return hit; }
public String getState() { return state; }
public String getTopYn() { return topYn; }
public String getFilename() { return filename; }
public void setNno(int nno) { this.nno = nno; }
public void setTitle(String title) { this.title = title; }
public void setContent(String content) { this.content = content; }
public void setRdate(String rdate) { this.rdate = rdate; }
public void setHit(String hit) { this.hit = hit; }
public void setState(String state) { this.state = state; }
public void setTopYn(String topYn) { this.topYn = topYn; }
public void setFilename(String filename) { this.filename = filename; }
}
게시글수정&삭제
NoticeController
@RequestMapping(value="/board/modify.do", method = RequestMethod.GET)
public String modify(int nno, Model model) {
NoticeVO noticeVO = noticeService.selectOne(nno);
model.addAttribute("view",noticeVO);
return "notice/modify";
}
@RequestMapping(value="/board/modify.do", method = RequestMethod.POST)
public String modify(NoticeVO noticeVO) {
int result = noticeService.update(noticeVO);
if(result > 0) {
System.out.println("글수정완료");
return "redirect:view.do?nno="+noticeVO.getNno();
}else {
System.out.println("글수정실패");
return "redirect:modify.do";
}
}
@RequestMapping(value="/board/delete.do", method = RequestMethod.POST)
public String delete(int nno) {
int result = noticeService.delete(nno);
if(result > 0) {
System.out.println("글삭제완료");
return "redirect:list.do";
}else {
System.out.println("글삭제실패");
return "redirect:view.do?nno="+nno;
}
}
NoticeService
public int update(NoticeVO noticeVO);
public int delete(int nno);
NoticeServiceImpl
@Override
public int update(NoticeVO noticeVO) {
return noticeDAO.update(noticeVO);
}
@Override
public int delete(int nno) {
return noticeDAO.delete(nno);
}
NoticeDAO
public int update(NoticeVO noticeVO) {
return sqlSession.update(namespace+".noticeUpdate",noticeVO);
}
public int delete(int nno) {
return sqlSession.update(namespace+".noticeDelete",nno);
}
noticeMapper
<update id="noticeUpdate" parameterType="noticeVO">
UPDATE notice_board
SET title=#{title},
content=#{content}
WHERE nno=#{nno}
</update>
<update id="noticeDelete" parameterType="int">
UPDATE notice_board
SET state='D'
WHERE nno=#{nno}
</update>
view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지글상세페이지</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/spring.css" />
</head>
<body>
<a href="<%= request.getContextPath() %>"><button class="sBtn">home</button></a><br>
<a href="list.do"><button class="sBtn">공지글목록</button></a>
<h2>공지사항상세페이지</h2><hr>
<!-- 회원목록 페이지에서 id 클릭시 상세정보 페이지로 이동합니다
이때 클릭한 아이디 회원 정보를 전부 상세페이지에 출력합니다
-->
<table>
<tr>
<th>글번호 : </th>
<td>${notice.nno}</td>
</tr>
<tr>
<th>제목 : </th>
<td>${notice.title}</td>
</tr>
<tr>
<th>작성자 : </th>
<td>${notice.uid}</td>
</tr>
<tr>
<th>등록일 : </th>
<td>${notice.rdate}</td>
</tr>
<tr>
<th>내용 : </th>
<td>
<div style="white-space: pre-wrap;"><c:out value="${notice.content}" /></div>
</td>
</tr>
</table>
<c:if test="${notice.uno == loginUser.uno}">
<a href="modify.do?nno=${notice.nno}"><button type="" style="width:80px; height:30px;">수정</button></a>
<button style="width:80px; height:30px;" onclick="document.getElementById('deleteFn').submit();">삭제</button>
<form action="delete.do" method="post" id="deleteFn">
<input type="hidden" name="nno" value="${notice.nno}">
</form>
</c:if>
</body>
</html>
<div style="white-space: pre-wrap;"><c:out value="${notice.content}" /></div>
white-space 속성:
- CSS 속성으로 텍스트가 표시되는 방식을 제어합니다.
- pre-wrap은 텍스트를 줄바꿈 없이 유지하지만, 필요할 경우 컨테이너 폭에 따라 자동으로 줄을 바꿉니다.
pre-wrap의 동작:
- HTML 코드에 작성된 줄바꿈(\n)과 공백이 그대로 유지됩니다.
- 하지만 텍스트가 컨테이너의 폭을 초과하면 자동으로 줄바꿈이 일어납니다.
만약 위의 코드를 밑처럼 사용하게 될 경우 첫줄의 앞에 띄어쓰기가 적용되어 보여집니다
<div style="white-space: pre-wrap;">
<c:out value="${notice.content}" />
</div>
modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지글수정</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/spring.css" />
<style>
textarea{
width: 250px;
border: 1px solid #EEEEEE;
border-radius: 5px;
}
input[type="text"]{
width: 250px;
}
</style>
</head>
<body>
<a href="<%= request.getContextPath() %>"><button class="sBtn">home</button></a>
<h2>공지글수정</h2><hr>
<form action="modify.do" method="post">
<table>
<tr>
<th>제목 : </th>
<td><input type="text" name="title" id="title" value="${view.title}"></td>
</tr>
<tr>
<th>내용 : </th>
<td>
<textarea name="content" id="content" rows="10" cols="40">${view.content}</textarea>
</td>
</tr>
</table>
<br>
<input type="hidden" name="nno" value="${view.nno}">
<button>수정하기</button>
</form>
</body>
</html>
'Spring' 카테고리의 다른 글
[Spring] AJAX 여러건의 데이터 받기 (0) | 2024.11.30 |
---|---|
[Spring] AJAX 한 건의 데이터 받기 (1) | 2024.11.29 |
[Spring] Spring MVC (2) | 2024.11.27 |
[Spring] @Controller (0) | 2024.11.25 |
[Spring] 스프링 MVC 프로젝트 (0) | 2024.11.24 |