728x90
Spring - 게시판 만들기(검색기능 구현), mybatis include, sql like, 삼항연산자, c:out
게시판의 검색 기능을 구현을 구현해보자
1. 실행화면
제목, 작성자, 내용, 전체로 검색할 수 있도록 검색옵션을 select태그로 사용
검색 결과물, 레코드의 수, 검색키워드, 검색키워드 결과화면에 같이 출력
2. 소스코드
01) 컨트롤러(흐름제어)
BoardController
// 01. 게시글 목록 @RequestMapping("list.do") // @RequestParam(defaultValue="") ==> 기본값 할당 public ModelAndView list(@RequestParam(defaultValue="title") String searchOption, @RequestParam(defaultValue="") String keyword) throws Exception{ List<BoardVO> list = boardService.listAll(searchOption, keyword); // 레코드의 갯수 int count = boardService.countArticle(searchOption, keyword); // ModelAndView - 모델과 뷰 ModelAndView mav = new ModelAndView(); /*mav.addObject("list", list); // 데이터를 저장 mav.addObject("count", count); mav.addObject("searchOption", searchOption); mav.addObject("keyword", keyword);*/ // 데이터를 맵에 저장 Map<String, Object> map = new HashMap<String, Object>(); map.put("list", list); // list map.put("count", count); // 레코드의 갯수 map.put("searchOption", searchOption); // 검색옵션 map.put("keyword", keyword); // 검색키워드 mav.addObject("map", map); // 맵에 저장된 데이터를 mav에 저장 mav.setViewName("board/list"); // 뷰를 list.jsp로 설정 return mav; // list.jsp로 List가 전달된다. } | cs |
02) 서비스(비지니스로직, DB연동 이외의 작업)
BoardService(인터페이스)
// 05. 게시글 전체 목록 ==> 검색옵션, 키워드 매개변수 추가 public List<BoardVO> listAll(String searchOption, String keyword) throws Exception; // 07. 게시글 레코드 갯수 메서드 추가 public int countArticle(String searchOption, String keyword) throws Exception; | cs |
BoardServiceImpl(인터페이스 구현 클래스)
// 05. 게시글 전체 목록 boardDAO.listAll메서드 호출 @Override public List<BoardVO> listAll(String searchOption, String keyword) throws Exception { return boardDao.listAll(searchOption, keyword); } // 07. 게시글 레코드 갯수 boardDao.countArticle메서드 @Override public int countArticle(String searchOption, String keyword) throws Exception { return boardDao.countArticle(searchOption, keyword); } | cs |
03) 모델(비지니스로직, DB연동 작업)
BoardDAO(인터페이스)
// 05. 게시글 전체 목록 ==> 검색옵션, 키워드 매개변수 추가 public List<BoardVO> listAll(String searchOption, String keyword) throws Exception; // 07. 게시글 레코드 갯수 메서드 추가 public int countArticle(String searchOption, String keyword) throws Exception; | cs |
BoardDAOImpl(인터페이스 구현 클래스)
// 05. 게시글 전체 목록 @Override public List<BoardVO> listAll(String searchOption, String keyword) throws Exception { // 검색옵션, 키워드 맵에 저장 Map<String, String> map = new HashMap<String, String>(); map.put("searchOption", searchOption); map.put("keyword", keyword); return SqlSession.selectList("board.listAll", map); } // 07. 게시글 레코드 갯수 @Override public int countArticle(String searchOption, String keyword) throws Exception { // 검색옵션, 키워드 맵에 저장 Map<String, String> map = new HashMap<String, String>(); map.put("searchOption", searchOption); map.put("keyword", keyword); return SqlSession.selectOne("board.countArticle", map); } | cs |
boardMapper.xml
<!-- 01_01. 게시글 전체목록 조회 및 검색 조회까지 --> <select id="listAll" resultType="com.example.spring02.model.board.dto.BoardVO"> SELECT bno, title, content, writer, regdate, viewcnt FROM tbl_board <!-- WHERE절을 include 태그로 삽입 --> <include refid="search"></include> ORDER BY bno desc, regdate desc </select> <!-- 01_02. 게시글 레코드 갯수 --> <select id="countArticle" resultType="int"> SELECT COUNT(*) FROM tbl_board <!-- WHERE절을 include 태그로 삽입 --> <include refid="search"></include> </select> <!-- sql code 조각 --> <!-- 반복되는 sql의 일부를 sql태그를 이용하여 따로 빼둘수 있다. --> <sql id="search"> <choose> <!-- 검색옵션이 전체 검색일 경우 --> <when test="searchOption == 'all'"> WHERE writer like '%'||#{keyword}||'%' OR content like '%'||#{keyword}||'%' OR title like '%'||#{keyword}||'%' </when> <!-- 전체 검색이 아닐 경우 --> <otherwise> WHERE ${searchOption} like '%'||#{keyword}||'%' </otherwise> </choose> </sql> | cs |
*mybatis include
mapper에서 동일한 쿼리를 반복하여 사용하는 경우 sql태그를 이용하여 쿼리를 따로 빼두고 원하는 위치에 include 태그를 사용하여 삽입하면 mapper에서 쿼리를 보다 간결하게 작성할 수 있다.
*sql like연산자
-- SQL LIKE 문법 SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern; | cs |
-- SQL LIKE 연산자 예제 -- City컬럼값이 "M"문자로 시작하는 레코드들을 조회 SELECT * FROM Customers WHERE City LIKE 'M%'; -- City컬럼값이 "s"문자로 끝나는 레코드들를 조회 SELECT * FROM Customers WHERE City LIKE '%s'; -- Country컬럼값에 "land"문자를 포함하는 레코드들을 조회 SELECT * FROM Customers WHERE Country LIKE '%land%'; -- Country컬럼값에 "land"문자를 포함하지않는 레코드들을 조회 SELECT * FROM Customers WHERE Country NOT LIKE '%land%'; | cs |
04) 뷰(화면)
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>게시글 목록</title> <%@ include file="../include/header.jsp" %> <script> $(document).ready(function(){ $("#btnWrite").click(function(){ // 페이지 주소 변경(이동) location.href = "${path}/board/write.do"; }); }); </script> </head> <body> <%@ include file="../include/menu.jsp" %> <h2>게시글 목록</h2> <form name="form1" method="post" action="${path}/board/list.do"> <select name="searchOption"> <!-- 검색조건을 검색처리후 결과화면에 보여주기위해 c:out 출력태그 사용, 삼항연산자 --> <option value="all" <c:out value="${map.searchOption == 'all'?'selected':''}"/> >제목+이름+제목</option> <option value="writer" <c:out value="${map.searchOption == 'writer'?'selected':''}"/> >이름</option> <option value="content" <c:out value="${map.searchOption == 'content'?'selected':''}"/> >내용</option> <option value="title" <c:out value="${map.searchOption == 'title'?'selected':''}"/> >제목</option> </select> <input name="keyword" value="${map.keyword}"> <input type="submit" value="조회"> <button type="button" id="btnWrite">글쓰기</button> </form> <!-- 레코드의 갯수를 출력 --> ${map.count}개의 게시물이 있습니다. <table border="1" width="600px"> <tr> <th>번호</th> <th>제목</th> <th>이름</th> <th>작성일</th> <th>조회수</th> </tr> <c:forEach var="row" items="${map.list}"> <tr> <td>${row.bno}</td> <td><a href="${path}/board/view.do?bno=${row.bno}">${row.title}</a></td> <td>${row.writer}</td> <td> <!-- 원하는 날짜형식으로 출력하기 위해 fmt태그 사용 --> <fmt:formatDate value="${row.regdate}" pattern="yyyy-MM-dd HH:mm:ss"/> </td> <td>${row.viewcnt}</td> </tr> </c:forEach> </table> </body> </html> | cs |
* jstl core태그 c:out
<c:out value="name"> name에 변수명, 화면에 출력 | cs |
* 삼항연산자
// 문법 첫번째 피연산자 ? 두번째 피연산자 : 세번째 피연산자; | cs |
첫번째 연산자는 불리언 값으로 평가 된다. 첫번째 피연산자 값이 true이면 두번째 피연자 값이 반환되고,
첫번째 연산자 값이 false이면 세번째 피연자 값이 반환된다. 뒤에 나올 if 조건문과 비슷한 결과를 얻을 수 있다.