4月18日
91216 ワード
きょう習った
掲示板出力、ブラウズ、修正、削除
package com.myapp.bbs.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.myapp.bbs.model.BoardVO;
@Mapper
public interface BoardMapper {
public void enroll(BoardVO board); // 게시판 글 등록
public List<BoardVO> getList(); // 게시판 모든 글 불러오기
public BoardVO getPage(int bno); // 게시글 불러오기
public int modify(BoardVO board); // 게시글 수정
public int delete(int bno); // 게시글 삭제
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- com.myapp.bbs.dao 패키지 안의 BoardMapper.java를 여기서 입력하겠다는 설정 -->
<mapper namespace="com.myapp.bbs.dao.BoardMapper">
<!-- board 테이블에 데이터 넣기 -->
<insert id="enroll" parameterType="BoardVO"> <!-- application.properties에 설정을 하지 않았다면 resultType="com.myapp.bbs.model.BoardVO" 라고 적었야함 -->
insert into board(title, content, writer)
values (#{title}, #{content}, #{writer});
</insert>
<!-- board 테이블에 등록된 모든 글 불러오기 -->
<select id="getList" resultType="BoardVO">
select *
from board
</select>
<!-- board 테이블의 글 불러오기 -->
<select id="getPage" resultType="BoardVO">
select *
from board
where bno=#{bno}
</select>
<!-- board 테이블의 글 수정하기 -->
<update id="modify">
update board
set title=#{title}, content=#{content}, updatedate=now()
where bno=#{bno}
</update>
<!-- board 테이블의 글 삭제하기 -->
<delete id="delete">
delete from board
where bno=#{bno}
</delete>
</mapper>
package com.myapp.bbs.service;
import java.util.List;
import com.myapp.bbs.model.BoardVO;
public interface BoardService {
public void enroll(BoardVO board); // 게시판 글 등록
public List<BoardVO> getList(); // 게시판 모든 글 불러오기
public BoardVO getPage(int bno); // 게시글 불러오기
public int modify(BoardVO board); // 게시글 수정하기
public int delete(int bno); // 게시글 삭제
}
package com.myapp.bbs.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.myapp.bbs.dao.BoardMapper;
import com.myapp.bbs.model.BoardVO;
@Service
public class BoardServiceImpl implements BoardService {
private BoardMapper boardMapper;
public BoardServiceImpl(BoardMapper boardMapper) {
this.boardMapper = boardMapper;
}
@Override
public void enroll(BoardVO board) {
boardMapper.enroll(board);
}
@Override
public List<BoardVO> getList() {
return boardMapper.getList();
}
@Override
public BoardVO getPage(int bno) {
return boardMapper.getPage(bno);
}
@Override
public int modify(BoardVO board) {
return boardMapper.modify(board);
}
@Override
public int delete(int bno) {
return boardMapper.delete(bno);
}
}
注意(なぜサービスクラスを作成しますか?依存項目を注入します)
https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/
package com.myapp.bbs.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.PathVariable;
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 com.myapp.bbs.model.BoardVO;
import com.myapp.bbs.service.BoardService;
import lombok.extern.java.Log;
@Controller
@RequestMapping("/board")
@Log // console의 Log 출력 (print out 대신 사용)
public class BoardController {
private BoardService boardService;
public BoardController(BoardService boardService) {
this.boardService = boardService;
}
@GetMapping("/list")
public String boardListGet(Model model) {
log.info("게시판 리스트 페이지 진입");
model.addAttribute("boardList", boardService.getList());
return "list";
}
/**
* 게시글 조회하기
* @param bno
* @param model
* @return
*/
// @GetMapping("/list/{bno}")
// public String getBoard(@PathVariable("bno") int bno, Model model) {
// model.addAttribute("board", boardService.getPage(bno));
// return "get";
// }
@GetMapping("/get")
public String getBoard(@RequestParam("bno") int bno, Model model) {
model.addAttribute("board", boardService.getPage(bno));
return "get";
}
@GetMapping("/enroll")
public String boardEnrollGet(Model model) {
log.info("게시판 등록 페이지 진입");
model.addAttribute("board", new BoardVO());
return "enroll";
}
@PostMapping("/enroll")
public String boardEnrollPost(BoardVO board, RedirectAttributes attr) {
boardService.enroll(board);
attr.addFlashAttribute("message", "게시글 등록 완료!");
return "redirect:/board/list"; // Post 다음 Redirect
}
// @GetMapping("/modify/{bno}")
// public String boardModify(@PathVariable("bno") int bno, Model model) {
// model.addAttribute("board", boardService.getPage(bno));
// return "modify";
// }
@GetMapping("/modify")
public String boardModifyGet(@RequestParam("bno") int bno, Model model) {
model.addAttribute("board", boardService.getPage(bno));
return "modify";
}
@PostMapping("/modify")
public String boardModifyPOST(BoardVO board, RedirectAttributes attr) {
boardService.modify(board);
attr.addFlashAttribute("message", "수정 성공");
return "redirect:/board/list"; // post에 redirect 하는 이유는 새로 고침 하면 중복전송이 되기 때문에 그것을 방지하기위해서 post - redirect - get 방식
}
@GetMapping("/delete")
public String boardDelete(@RequestParam("bno") int bno) {
boardService.delete(bno);
return "redirect:/board/list";
}
ページ
ホームページ
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/head :: 헤드"></head>
<body class="g-sidenav-show bg-gray-200">
<aside th:replace="fragments/aside :: 어사이드"></aside>
<!-- 메인 컨텐트 시작 -->
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg">
<!-- 상단 네브바 -->
<nav th:replace="fragments/nav :: 네브"></nav>
<!-- 컨텐츠 시작 -->
<div class="container-fluid py-4">
<!-- 빈 컨텐츠 (여기서 시작)-->
<a th:href="@{/board/enroll}" class="btn btn-primary my-3">게시글 등록</a>
<div class="card">
<div class="table-responsive">
<table class="table align-items-center mb-0">
<thead>
<tr>
<th class="text-center text-secondary text-xxs font-weight-bolder opacity-7">No</th>
<th class="text-center text-secondary text-xxs font-weight-bolder opacity-7">제목</th>
<th class="text-center text-secondary text-xxs font-weight-bolder opacity-7">작성자</th>
<th class="text-center text-secondary text-xxs font-weight-bolder opacity-7">등록일</th>
<th class="text-center text-secondary text-xxs font-weight-bolder opacity-7">수정일</th>
<th class="text-secondary opacity-7">기타</th>
</tr>
</thead>
<tbody>
<tr th:each="board : ${boardList}">
<td class="align-middle text-center">
<span class="text-secondary text-sx" th:text="${board.bno}"></span>
</td>
<td class="align-middle text-center">
<!-- thymeleaf문법에서는 Parameter로 넘길 때는 ()안에 변수명과 값을 넣어준다 -->
<a th:href="@{/board/get(bno=${board.bno})}"><span class="text-secondary text-sx" th:text="${board.title}"></span></a>
<!-- <a th:href="@{'/board/list/' + ${board.bno}}"><span class="text-secondary text-sx" th:text="${board.title}"></span></a> -->
</td>
<td class="align-middle text-center">
<span class="text-secondary text-sx" th:text="${board.writer}"></span>
</td>
<td class="align-middle text-center">
<!-- 연-월-일 am,pm 시:분:초, thymeleaf문법에서 String타입에서 Date타입을 나타낼때 이런식으로 사용-->
<span class="text-secondary text-sx" th:text="${#temporals.format(board.regdate, 'yyyy-MM-dd a hh:mm:ss')}"></span>
</td>
<td class="align-middle text-center">
<span class="text-secondary text-sx" th:text="${#temporals.format(board.updateDate, 'yyyy-MM-dd a hh:mm:ss')}"></span>
</td>
</tr>
</div>
</main>
<!-- 오른쪽 숨김창 , JS 링크들 -->
<hidden th:replace="fragments/hidden :: 숨김창"></hidden>
<jslink th:replace="fragments/jslink :: 링크"></jslink>
<script>
document.getElementById('pageName').textContent = '게시판 목록';
</script>
</body>
</html>
注意(Thymeleaf構文から日付タイプを変換)
https://ssd0908.tistory.com/32
投稿ページの表示
<!-- 메인 컨텐트 시작 -->
<main class="main-content mt-0">
<section>
<div class="page-header min-vh-100">
<div class="container">
<div class="row">
<div class="col-md-10 ms-auto me-auto">
<div class="card card-plain">
<div class="card-body bg-white">
<table class="table table-condensed">
<tr>
<th>번호</th>
<td th:text="${board.bno}"></td>
<th>작성일</th>
<td th:text="${#temporals.format(board.regdate, 'yyyy-MM-dd a hh:mm:ss')}"></td>
</tr>
<tr>
<th>작성자</th>
<td th:text="${board.writer}"></td>
<th>수정일</th>
<td th:text="${#temporals.format(board.updateDate, 'yyyy-MM-dd a hh:mm:ss')}"></td>
</tr>
<tr>
<th>제목</th>
<td colspan="3" th:text="${board.title}"></td>
</tr>
<tr>
<th>내용</th>
<td colspan="3" th:text="${board.content}"></td>
</tr>
</table>
</div>
<div class="card-footer bg-white text-center pt-0 px-lg-2 px-1">
<a th:href="@{/board/list}" class="btn btn-success">목록</a>
<!-- <a th:href="@{'/board/modify/' + ${board.bno}}" class="btn btn-secondary">수정</a> -->
<a th:href="@{/board/modify(bno=${board.bno})}" class="btn btn-secondary">수정</a>
<button onclick="deleteConfirm()" class="btn btn-danger">삭제</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- 오른쪽 숨김창 , JS 링크들 -->
<hidden th:replace="fragments/hidden :: 숨김창"></hidden>
<jslink th:replace="fragments/jslink :: 링크"></jslink>
<script>
function deleteConfirm() {
if (confirm('정말로 삭제할까요?')) {
location.href = '/board/delete?bno=' + '[[${board.bno}]]';
}
}
</script>
投稿ページの変更
<!-- 메인 컨텐트 시작 -->
<main class="main-content mt-0">
<section>
<div class="page-header min-vh-100">
<div class="container">
<div class="row">
<div class="col-md-10 ms-auto me-auto">
<div class="card card-plain">
<div class="card-header">
<h4 class="font-weight-bolder">게시글 수정</h4>
<p class="mb-0">게시글을 수정해주세요.</p>
</div>
<div class="card-body bg-white">
<form role="form" th:action="@{/board/modify}" method="post" th:object="${board}">
<input type="hidden" th:field="*{bno}" />
<!-- is-filled 없으면 label의 제목 텍스트와 입력된 값이 겹쳐서 출력됨-->
<div class="input-group input-group-outline mb-3 is-filled">
<label class="form-label">제목</label>
<input type="text" class="form-control" th:field="*{title}" required />
</div>
<div class="input-group input-group-outline mb-3">
<div class="input-group input-group-dynamic">
<textarea th:field="*{content}" class="form-control" rows="5" placeholder="내용을 적어주세요." spellcheck="false" required></textarea>
</div>
</div>
<div class="input-group input-group-outline mb-3 is-filled">
<label class="form-label">작가</label>
<input type="text" class="form-control" th:field="*{writer}" readonly required />
</div>
<div class="text-center">
<a th:href="@{/board/list}" class="btn btn-danger">수정 취소</a>
<button type="submit" class="btn btn-success">수정 완료</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
Reference
この問題について(4月18日), 我々は、より多くの情報をここで見つけました https://velog.io/@tutu10000/4월-18일テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol