4月18日

91216 ワード

きょう習った

  • 掲示板の作成(2)
  • 掲示板出力、ブラウズ、修正、削除

  • Mapper
  • 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); // 게시글 삭제
    }
  • Mapper.xml
  • <?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>
  • Service
  • 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); // 게시글 삭제
    }
  • Service Impl
  • クラスに@Serviceチェック
  • を貼り付けます.
    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>