저장소
테이블 15
파일명 BoardRepository.java
package com.example.repository;
import java.util.Collection;
import java.util.List;
import com.example.entity.Board;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface BoardRepository extends MongoRepository<Board, Long>{
// 정확하게 일치 findBy변수명
// 작성자가 'a'인 사람의 목록 조회
List<Board> findByTitle(String title);
List<Board> findByWriter(String writer);
// 조회수가 100인것 목록으로 조회
List<Board> findByHit(long hit);
// 크다 작다
// 조회수가 200미만 인것 목록으로 조회
List<Board> findByHitLessThan(long hit);
// 조회수가 300이상 인것 목록으로 조회
List<Board> findByHitGreaterThanEqual(long hit);
// 여러개 포함,
// 글번호가 컬렉션에 담긴 1, 5, 7만 조회
List<Board> findByNoIn(Collection<Long> nos);
List<Board> findByNoNotIn(Collection<Long> nos);
// 직접 구현
// 컨트롤러에서 bRepository.getBoardTitle("제목")
@Query(value = "{'title' : ?0}") // 몽고DB 문법을 알아야함
List<Board> getBoardTitle(String title);
@Query(value = "{'writer' : ?0}")
List<Board> getBoardWriter(String writer);
@Query(value = "{'hit' : ?0}")
List<Board> getBoardHit(long hit);
@Query(value = "{title : {$regex : ?0}}" )
List<Board> getBoardTitleLike(String title);
// ex) 컨트롤러에서 bRepository.getBoardTitleLike("가")
// 제목에 "가" 내용이 포함된것 가져옴
// 조회수가 n보다 작다 <e, >, >e
@Query(value = "{hit : {$lt : ?0}}" )
List<Board> getBoardHitLt(long hit);
// 제목과 장성자가 일치(AND)
@Query(value = "{title : ?0, writer : ?1}" )
// @Query(value = "{$and : [{title : ?0, writer : ?1}] }" )
List<Board> getBoardTitleAndWriter(String title, String writer);
// 제목과 작성자 둘중에 하나(OR)
@Query(value = "{$or : [{title : ?0, writer : ?1}] }" )
List<Board> getBoardTitleOrWriter(String title, String writer);
// 전체 제목에 포함된것 중에서 개수
@Query(value = "{title : {$regex : ?0}}", count = true )
long getBoardTitleLikeCount(String title);
// 작성자가 정확하게 일치하는 목록
@Query(value = "{'writer' : ?0}", sort = "{_id:-1}")
List<Board> getBoardWriterSort(String writer);
}
파일명 BoardController.java
package com.example.controller;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.example.entity.Board;
import com.example.repository.BoardRepository;
import com.example.service.SequenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
@Controller
@RequestMapping(value = "/board")
public class BoardController {
// 서비스 => mybatis => 설계 + 구현(SQL문)
// 저장소 => jpa, hibernate => 설계 + 구현
@Autowired
BoardRepository bRepository;
@Autowired
SequenceService sequenceService;
@Autowired
HttpSession httpSession;
@GetMapping(value = "/selectlist")
public String selectGET(Model model){
List<Board> list = bRepository.findAll();
model.addAttribute("list", list);
return "board/selectlist";
}
@GetMapping(value = "/insert")
public String insertGET(){
return "board/insert";
}
@PostMapping(value = "/insert")
public String insertPOST(
Model model,
@ModelAttribute Board board){
System.out.println(board.toString());
// "SEQ_BOARD4_NO"
board.setNo( sequenceService.generatedSequence("SEQ_BOARD4_NO"));
board.setRegdate(new Date());
Board retBoard = bRepository.save(board);
if(retBoard != null){
model.addAttribute("msg","작성 완료");
model.addAttribute("url","/board/selectlist");
return "alert";
}
return "redirect:/board/insert";
}
// RedirectAttributes POST에서 GET으로 데이터를 전송
@PostMapping(value = "/action")
public String actionPOST(
Model model,
RedirectAttributes redirectAttributes,
@RequestParam(name = "btn")String btn,
@RequestParam(name = "rad")long no){
try {
System.out.println("누른버튼 : "+btn);
System.out.println("체크한 라디오 : "+no);
// int, long, char => if(btn == "1개 삭제")가능 (String은 불가능)
// String => if( btn.equals("1개 삭제")) 가용해야함
if( btn.equals("1개 삭제") ){
bRepository.deleteById(no);
model.addAttribute("msg","삭제되었습니다.");
model.addAttribute("url","/board/selectlist");
return "alert"; // 알림창 띄우고 url변경 자동화
}
else if(btn.equals("1개 수정") ){
// httpSession.setAttribute("rad", no);
// GET방식 url에 parameter로 붙임
redirectAttributes.addAttribute("no", no);
// POST방식 1번만 전송 새로고침시 데이터는 소멸
// 세션에 추가하는 방식
redirectAttributes.addFlashAttribute("no1", no);
return "redirect:/board/update";
// bRepository.save를 이용 단, _id가 조건으로 됨.
}
return "redirect:/board/selectlist";
} catch (Exception e) {
e.printStackTrace();
return "redirect:/home";
}
}
@GetMapping(value = "/update")
public String updateGET(
Model model,
HttpServletRequest request,
@RequestParam(name = "no")long no ) {
//long no = (long)httpSession.getAttribute("rad");
// Optional<Board> obj = bRepository.findById(no);
// Board board = obj.get();
// model.addAttribute("board", board);
System.out.println("no : "+no);
Map< String, ? > map = RequestContextUtils.getInputFlashMap(request);
if(map != null){
long no1 = (long)map.get("no1");
System.out.println("no1 : "+ no1);
}
Board board = bRepository.findById(no).orElse(null);
model.addAttribute("board", board);
return "board/update";
}
@PostMapping(value = "/update")
public String updatePOST(
Model model,
@ModelAttribute Board board
// @RequestParam(name = "no")long no,
// @RequestParam(name = "title")String title,
// @RequestParam(name = "content")String content
){
try{
// Board board = new Board();
// board.setNo(no);
// board.setTitle(title);
// board.setContent(content);
// 추가 => 기본키를 다르게 해서 저장
// 수정 => 기본키에 해당하는 글번호를 동일하게 새로저장
// 기존내용을 읽음
Board board1 = bRepository.findById(board.getNo()).orElse(null);
// 변경할 항목만 board1에 다시 저장
board1.setTitle(board.getTitle());
board1.setContent(board.getContent());
board1.setWriter(board.getWriter());
// 최종적으로 board1의 값을 저장
bRepository.save(board1);
model.addAttribute("msg","수정되었습니다.");
model.addAttribute("url","/board/selectlist");
return "alert"; // 알림창 띄우고 url변경 자동화
}
catch(Exception e){
e.printStackTrace();
return "redirect:/home";
}
}
// 127.0.0.1:8080/board/selectfind
@GetMapping(value = "/selectfind")
public String selectfindGET(Model model,
@RequestParam(name = "type", defaultValue = "", required = false )String type,
@RequestParam(name = "text", defaultValue = "", required = false )String text,
@RequestParam(name = "type1", defaultValue = "0", required = false )String type1,
@RequestParam(name = "hit", defaultValue = "0", required = false )long hit1,
@RequestParam(name = "type2", defaultValue = "0", required = false )String type2,
@RequestParam(name = "no", defaultValue = "0", required = false )List<Long> no
) {
List<Board> list = null;
// 1. 정확하게 일치하는 항목 가져오기
if(type.equals("title")){
// list = bRepository.findByTitle(text);
list = bRepository.getBoardTitle(text);
}
else if(type.equals("writer")){
// list = bRepository.findByWriter(text);
list = bRepository.getBoardWriter(text);
}
else if(type.equals("hit")){
long hit = 0L;
try{
// 문자로 되어 있는 숫자를 숫자형으로변경
// "1234" => 1234
// "" => X
hit = Long.parseLong(text);
}
catch(Exception e){
hit = 0L;
}
// list = bRepository.findByHit( hit );
list = bRepository.getBoardHit( hit );
}
if(text.length() == 0 ){
list = bRepository.findAll();
}
// 2. 조회수가 이상, 미만 조회하기
if(type1.equals("1")){ // 이상
list = bRepository.findByHitGreaterThanEqual(hit1);
}
else if(type1.equals("2")){ // 미만
list = bRepository.findByHitLessThan(hit1);
}
// 3. 포함, 포함하지 않음
if(type2.equals("1")){ //포함
list = bRepository.findByNoIn(no);
}
else if(type2.equals("2")) { //포함X
list = bRepository.findByNoNotIn(no);
}
model.addAttribute("list", list);
return "board/selectfind";
}
}
파일명 selectlist.jsp
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판</title>
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}"/>
<script type="text/javascript" src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<div style="padding: 20px;">
<h3>board list</h3>
<hr />
<a th:href="@{/board/insert}" >글쓰기</a>
<form th:action="@{/board/action}" method="post">
<input type="submit" name="btn" value="1개 삭제" class="btn btn-primary"/>
<input type="submit" name="btn" value="1개 수정" class="btn btn-primary"/>
<hr />
<table class="table table-striped">
<tr>
<th>radio</th>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
</tr>
<tr th:each="tmp, idx : ${list}">
<td><input type="radio" name="rad" th:value="${tmp.no}" /></td>
<td th:text="${tmp.no}"></td>
<td th:text="${tmp.title}"></td>
<td th:text="${tmp.writer}"></td>
<td th:text="${tmp.hit}"></td>
<td th:text="${tmp.regdate}"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
파일명 selectfind.jsp
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판</title>
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}"/>
<script type="text/javascript" src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<div style="padding: 20px;">
<h3>board find</h3>
<hr />
<h5>1. 정확하게 일치하는 항목 가져오기</h5>
<form th:action="@{/board/selectfind}" method="get">
<select name="type" >
<option value="title">제목</option>
<option value="writer">작성자</option>
<option value="hit">조회수</option>
</select>
<input type="text" name="text" placeholder="검색어" />
<input type="submit" value="검색" />
</form>
<hr />
<h5>2. 조회수가 이상, 미만 조회하기</h5>
<form th:action="@{/board/selectfind}" method="get">
<select name="type1" >
<option value="1">이상</option>
<option value="2">미만</option>
</select>
<input type="text" name="hit" placeholder="검색어" />
<input type="submit" value="검색" />
</form>
<hr />
<h5>3. 포함, 포함하지 않음</h5>
<form th:action="@{/board/selectfind}" method="get">
<select name="type2">
<option value="1">포함</option>
<option value="2">포함하지않음</option>
</select>
<input type="number" name="no" placeholder="글번호1" />
<input type="number" name="no" placeholder="글번호2" />
<input type="number" name="no" placeholder="글번호3" />
<input type="submit" value="검색" />
</form>
<hr />
<table class="table table-sm">
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
</tr>
<tr th:each="tmp, idx : ${list}">
<td th:text="${tmp.no}"></td>
<td th:text="${tmp.title}"></td>
<td th:text="${tmp.writer}"></td>
<td th:text="${tmp.hit}"></td>
<td th:text="${tmp.regdate}"></td>
</tr>
</table>
</div>
</body>
</html>
파일명 update.jsp
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판 수정</title>
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}"/>
<script type="text/javascript" src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<div style="padding: 20px;">
<h3>board update</h3>
<hr />
<form th:action="@{/board/update}" method="post">
<input type="hidden" th:value="${board.no}" name="no" readonly/>
<label style="width:95px; height: 30px; display:inline-block;">제목 : </label>
<input type="text" th:value="${board.title}" name="title"/></br>
<label style="width:95px; height: 30px; display:inline-block;">내용 : </label>
<input type="text" th:value="${board.content}" name="content"/></br>
<label style="width:95px; height: 30px; display:inline-block;">작성자 : </label>
<input type="text" th:value="${board.writer}" name="writer"/></br>
<label style="width:95px; height: 30px; display:inline-block;"></label>
<input type="submit" class="btn btn-primary" value="수정하기" />
<a th:href="@{/board/selectlist}" class="btn btn-primary">글목록</a>
</form>
</div>
</body>
</html>