1. 검색기능
- 쿼리작성
- search_cnt - 검색 후 페이지의 수를 지정하기 위한 쿼리
<!-- 검색한 게시물 수 -->
<select id="search_cnt" resultType="int">
select count(*) from board where title LIKE CONCAT('%', #{search}, '%')
</select>
- search - 검색 쿼리
<!-- 검색 -->
<select id="search" resultType="BoardDto" parameterType="map">
SELECT *
FROM board
WHERE title LIKE CONCAT('%', #{search}, '%')
ORDER BY bno desc
LIMIT #{offset}, #{nav}
</select>
public interface BoardDao {
int count();
List<BoardDto> selectPage(Map map);
BoardDto select(int bno);
void insert(BoardDto boardDto);
int update(BoardDto boardDto);
int delete(Map map);
void view_increase(int bno);
List<BoardDto> search(Map map);
int search_cnt(String search);
}
- BoarddaoImpl 클래스 - MyBatis를 이용해 컨트롤러에서 처리한 요청을 DB에 전달해준다.
@Repository
public class BoardDaoImpl implements BoardDao {
@Autowired
SqlSession session;
String namespace = "com.example.demo.domain.BoardMapper.";
@Override
public int count(){
return session.selectOne(namespace+"count");
}
@Override
public List<BoardDto> selectPage(Map map){
return session.selectList(namespace+"selectPage", map);
}
@Override
public BoardDto select(int bno){
return session.selectOne(namespace+"select", bno);
}
@Override
public void insert(BoardDto boardDto){
session.insert(namespace+"insert", boardDto);
}
@Override
public int update(BoardDto boardDto){
return session.update(namespace+"update", boardDto);
}
@Override
public int delete(Map map){
return session.delete(namespace+"delete", map);
}
@Override
public void view_increase(int bno){
session.update(namespace+"view_increase", bno);
}
@Override
public List<BoardDto> search(Map map) { return session.selectList(namespace+"search", map); }
@Override
public int search_cnt(String search){
return session.selectOne(namespace+"search_cnt", search);
}
}
- BoardDto - board테이블의 정보를 전달할 객체
@Setter
@Getter
@ToString
public class BoardDto {
private int bno;
private String title;
private String content;
private String writer;
private int view_cnt;
private int comment_cnt;
private String reg_date;
private String up_date;
BoardDto(){}
public BoardDto(String title, String content, String writer) {
this.title = title;
this.content = content;
this.writer = writer;
}
public void setReg_date(Date reg_date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
this.reg_date = sdf.format(reg_date);
}
public void setUp_date(Date up_date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
this.up_date = sdf.format(up_date);
}
}
- Controller클래스
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardDao boardDao;
@GetMapping("/insert")
public String insert(Integer page, Integer pageSize, Integer nav, BoardDto boardDto, Model m){
System.out.println("getInsert/page = " + page);
System.out.println("getInsert/pageSize = " + pageSize);
System.out.println("getInsert/boardDto = " + boardDto);
System.out.println("getInsert/nav = " + nav);
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
m.addAttribute("menu", "write");
m.addAttribute("nav", nav);
System.out.println("m.getAttribute(\"menu\") = " + m.getAttribute("menu"));
return "board";
}
// 게시물 추가
@PostMapping("/insert")
public String insert(Integer page, Integer pageSize, Integer nav, BoardDto boardDto, RedirectAttributes rattr){
System.out.println("insert/page = " + page);
System.out.println("insert/pageSize = " + pageSize);
System.out.println("insert/boardDto = " + boardDto);
System.out.println("insert/nav = " + nav);
// BoardDto boardDto2 = new BoardDto(boardDto.getTitle(), boardDto.getContent(), (String)session.getAttribute("id"));
BoardDto boardDto2 = new BoardDto(boardDto.getTitle(), boardDto.getContent(), boardDto.getWriter());
boardDao.insert(boardDto2);
return "redirect:/board/list?page="+page+"&pageSize="+pageSize+"&nav="+nav;
}
// 게시물 수정
@PostMapping("/update")
public String update(Integer page, Integer pageSize, Integer nav,BoardDto boardDto, String search, RedirectAttributes rattr){
System.out.println("update/boardDto = " + boardDto);
int rowCnt = boardDao.update(boardDto);
rattr.addFlashAttribute("boardDto",boardDto);
System.out.println("update/page = " + page);
System.out.println("update/pageSize = " + pageSize);
System.out.println("update/nav = " + nav);
System.out.println("update/boardDto.getBno() = " + boardDto.getBno());
return "redirect:/board/read?page="+page+"&pageSize="+pageSize+"&nav="+nav+"&search="+search;
}
// 게시물 삭제
@PostMapping("/delete")
public String delete(Integer page, Integer pageSize, Integer nav,BoardDto boardDto, String search, Model m, RedirectAttributes rattr, HttpSession session){
Map map = new HashMap();
map.put("bno", boardDto.getBno());
map.put("writer", boardDto.getWriter());
System.out.println("delete/boardDto.getWriter() = " + boardDto.getWriter());
try{
int rowCnt=0;
// if(session.getAttribute("id").equals(boardDto.getWriter()))
rowCnt = boardDao.delete(map);
rattr.addFlashAttribute("page", page);
rattr.addFlashAttribute("pageSize", pageSize);
rattr.addFlashAttribute("nav", nav);
rattr.addFlashAttribute("search", search);
System.out.println("delete/page = " + page);
System.out.println("delete/pageSize = " + pageSize);
System.out.println("delete/nav = " + nav);
System.out.println("delete/boardDto = " + boardDto);
return "redirect:/board/list?page="+page+"&pageSize="+pageSize+"&nav="+nav+"&search="+search;
}catch(Exception e){
e.printStackTrace();
return "board";
}
}
// 게시물 읽어오기
@GetMapping("/read")
public String read(Integer page, Integer pageSize, Integer nav, String search,BoardDto boardDto, Model m){
// boardList.html 에서 title 을 누르면 /board/read 페이지로 넘어온다.
boardDao.view_increase(boardDto.getBno());
BoardDto boardDto2 = boardDao.select(boardDto.getBno());
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
m.addAttribute("nav", nav);
m.addAttribute("boardDto", boardDto2);
m.addAttribute("search", search);
System.out.println("read/page = " + page);
System.out.println("read/pageSize = " + pageSize);
System.out.println("read/nav = " + nav);
System.out.println("read/boardDto = " + boardDto2);
return "board";
}
// 게시판 목록
@GetMapping("/list")
public String list(Integer page, Integer pageSize, Integer nav, String search,Model m){
if(page==null)
page=1;
if(pageSize==null)
pageSize=10;
if(nav==null)
nav=20;
if(search==null)
search="*";
System.out.println("list/page = " + page);
System.out.println("list/pageSize = " + pageSize);
System.out.println("list/nav = " + nav);
System.out.println("list/search = " + search);
Map map = new HashMap();
map.put("offset", (page-1)*nav);
map.put("nav", nav);
map.put("search", search);
List<BoardDto> list;
int cnt=boardDao.count();
if(search.equals("*")){
list = boardDao.selectPage(map);
}else {
list = boardDao.search(map);
cnt = boardDao.search_cnt(search);
}
PageHandler ph = new PageHandler(cnt, page, pageSize, nav);
m.addAttribute("list", list);
m.addAttribute("page",page);
m.addAttribute("pageSize",pageSize);
m.addAttribute("nav", nav);
m.addAttribute("ph",ph);
m.addAttribute("search", search);
System.out.println("list/page = " + page);
System.out.println("list/pageSize = " + pageSize);
System.out.println("list/nav = " + nav);
System.out.println("list/search = " + search);
System.out.println("list/ph = " + ph);
return "boardList";
}
}
- board.html - 게시물을 보여주는 페이지, 생성,삭제,수정,읽기 가능
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<title>Board</title>
</head>
<body>
<script>
let menu = "[[${menu}]]"
if(menu=="write")
$(document).ready(function(){
$("input[name=writer]").attr('readonly', false).attr('value', "");
$("input[name=title]").attr('readonly', false).attr('value', "");
$("textarea[name=content]").attr('readonly', false).html("");
$('#creBtn').html("완료");
$('h2').html("게시글 작성");
});
</script>
<h2 style="text-align:center">게시물 읽기</h2>
<form id="form">
<input name="bno" type="hidden" th:value="${boardDto.bno}" readonly/>
<input name="title" type="text" th:value="${boardDto.title}" readonly style="position:absolute; width:40%;height:5%;right:30%; font-size:20px"/>
<textarea name="content" th:text="${boardDto.content}" readonly style="position:absolute; width:40%;right:30%; height:35%; top:15%; font-size:15px"></textarea>
<input name="writer" type="text" th:value="${boardDto.writer}" readonly style="position:absolute; width:100px;right:30%; top:52%; font-size:20px"/>
<!-- 데이터 전달용 -->
<input name="page" type="hidden" th:value="${page}" readonly/>
<input name="pageSize" type="hidden" th:value="${pageSize}" readonly/>
<input name="nav" type="hidden" th:value="${nav}" readonly />
<input name="search" type="hidden" th:value="${search}" readonly />
<input name="check" type="hidden" readonly />
<!-- 데이터 전달용 -->
<button type="button" id="creBtn" style="position:absolute; right:39%; top:56%">새글쓰기</button>
<button type="button" id="wrtBtn" style="position:absolute; right:33%; top:56%">수정</button>
<button type="button" id="delBtn" style="position:absolute; right:36%; top:56%">삭제</button>
<button type="button" id="listBtn" style="position:absolute; right:30%; top:56%">목록</button>
</form>
<script>
$(document).ready(function(){
// 생성
$('#creBtn').on("click", function(){
let form = $('#form');
let menu = "[[${menu}]]";
if(menu=="write"){
form.attr("action", "/board/insert");
form.attr("method", "post");
form.submit();
} else {
form.attr("action", "/board/insert");
form.attr("method", "get");
form.submit();
}
})
// 읽기
$('#listBtn').on("click", function(){
let form = $('#form');
form.attr("action", "/board/list");
form.attr("method", "get");
form.submit();
})
// 삭제
$('#delBtn').on("click",function(){
if(!confirm("정말로 삭제하시겠습니까?")) return;
let form = $('#form');
form.attr("action", "/board/delete");
form.attr("method", "post");
form.submit();
});
// 수정
$('#wrtBtn').on("click", function(){
let form = $('#form');
let isReadOnly = $("input[name=title]").attr('readonly');
if(isReadOnly=='readonly'){
$("textarea[name=content]").removeAttr("readonly");
$("input[name=title]").removeAttr("readonly");
$('h2').html('게시물 수정');
$('#wrtBtn').html('수정완료');
return;
}
if(!confirm("변경하시겠습니까?")) return;
form.attr("action", "/board/update");
form.attr("method", "post");
form.submit();
});
});
</script>
</body>
</html>
- boardList - 게시물 페이지를 보여주기위한 페이지
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<title>BoardList</title>
</head>
<body>
<span>
<br>
<h1 style="text-align:center; position:relative">게시물 목록</h1>
<br>
<form id="search_form" action="/board/list" method="get">
<input type="search" style="position:absolute; top:13%" placeholder="검색창" id="search" name="search">
</form>
<form id="form" action="/board/list" method="get">
<select style="position:absolute; right:10px; top:13%" id="nav" name="nav">
<option>게시물 표시 수</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
</select>
</form>
</span>
<table border="1px" width="100%">
<tr style="text-align:center">
<td>번호</td>
<td width="50%">제목</td>
<td>내용</td>
<td>작성자</td>
<td>조회수</td>
<td>작성일</td>
<td>수정일</td>
</tr>
<tr th:each="item : ${list}">
<td th:text="${item.bno}"></td>
<td><a th:href="@{'/board/read?page='+${page}+'&pageSize='+${pageSize}+'&bno='+${item.bno}+'&nav='+${nav}+'&search='+${search}}"><span th:text="${item.title}"></span></a></td>
<td th:text="${item.content}"></td>
<td th:text="${item.writer}"></td>
<td th:text="${item.view_cnt}"></td>
<td th:text="${item.reg_date}"></td>
<td th:text="${item.up_date}"></td>
</tr>
</table>
<br>
<div style="text-align:center; position:relative">
<th:block th:if="${ph.beginPage}>1">
<a th:href="@{'/board/list?page='+${ph.beginPage+-1}+ '&pageSize=' + ${pageSize} + '&nav=' + ${nav} +'&search='+${search}}"><</a>
</th:block>
<th:block th:each="i : ${#numbers.sequence(ph.beginPage, ph.endPage)}">
<a th:href="@{'/board/list?page=' + ${i} + '&pageSize=' + ${pageSize} + '&nav=' + ${nav} +'&search='+${search}}"><span th:text="${i}">1</span></a>
</th:block>
<th:block th:if="${ph.endPage}<${ph.page_cnt}">
<a th:href="@{'/board/list?page='+${ph.endPage+1}+ '&pageSize=' + ${pageSize} + '&nav=' + ${nav} +'&search='+${search}}">></a>
</th:block>
<form id="write_form">
<button type="button" id="wriBtn" style="position:absolute; right:20px;">글쓰기</button>
<input type="hidden" name="page" id="page" th:value="${page}"/>
<input type="hidden" name="pageSize" id="pageSize" th:value="${pageSize}"/>
<input type="hidden" name="nav" id="nav2" th:value="${nav}"/>
</form>
</div>
<script>
$(document).ready(function(){
$('#nav').on('change',function(){
$('#form').submit();
});
$('#wriBtn').on('click', function(){
$('#write_form').attr("action", "/board/insert");
$('#write_form').attr("method", "get");
$('#write_form').submit();
});
});
</script>
</body>
</html>
- boardList페이지, 제목을 눌러 들어갈수있고, 검색, 게시물의 수 지정, 글쓰기, 페이지 이동 등의 기능이구현되어있다.
- 게시물 갯수 조절
- 게시물 검색(9를 검색했다)
- 게시물에 들어갔다 나와도 원래 있던 페이지로 돌아간다.
- 2페이지의 게시물99를 들어갔다가 나오면 다시 2페이지로 나온다.
'MyBatis' 카테고리의 다른 글
10. REST API와 Ajax - 패스트캠퍼스 백엔드 부트캠프 3기 (2) | 2025.03.17 |
---|---|
8. SpringBoot로 페이징과 CRUD 작성 - 패스트캠퍼스 백엔드 부트캠프 3기 (2) | 2025.03.05 |
7. SpringBoot로 MyBatis연동하기 - 패스트캠퍼스 백엔드 부트캠프 3기 (1) | 2025.03.04 |
6. 게시판 읽기, 쓰기, 삭제, 수정 기능구현(2) - 패스트캠퍼스 백엔드 부트캠프 3기 (0) | 2025.03.04 |
5. 게시판 읽기, 쓰기, 삭제, 수정 기능구현(1) - 패스트캠퍼스 백엔드 부트캠프 3기 (2) | 2025.03.03 |