4월 21일

SJY0000·2022년 4월 21일
0

Springboot

목록 보기
20/24

오늘 배운 것

  • 검색기능(2)
  • 댓글(1)

검색기능(2)

검색조건 추가

  • Criteria클래스에 같이 담아서 보낼 수 있도록 함(get,set 또는 @Data 필수)
	private String keyword; // 검색어 키워드
	
	private String type; // 검색 타입(View에서 선택된)
	
	private String[] typeArr; // 검색 타입 배열(type을 배열로 변환)
  • boardMapper.xml에 검색 조건문 추가
  • if문으로 검색어가 있을 경우 검색조건문을 넣을 수 있도록 함
<!-- 검색 조건문 -->
	<sql id="criteria">
		<trim prefix="where (" suffix=")" prefixOverrides="OR">
			<foreach collection="typeArr" item="type">
				<trim prefix="OR">
					<choose>
						<when test="type == 'T'.toString()">
							title like concat('%',#{keyword},'%')
						</when>
						<when test="type == 'C'.toString()">
							content like concat('%',#{keyword},'%')
						</when>
						<when test="type == 'W'.toString()">
							writer like concat('%',#{keyword},'%')
						</when>
					</choose>
				</trim>
			</foreach>
		</trim>
	</sql>

    <select id="getListPaging" resultType="BoardVO">
    	select *
    	from ( 
    		select bno, title, writer, regdate, updatedate
    		from board
    		
    		<if test="keyword != null">
    			<include refid="criteria"></include>
    		</if>
    		
    		order by bno desc
    		) as T1
    	limit #{skip}, #{amount}
    </select>

     <select id="getTotal" resultType="int">
     	select count(*)
     	from board
     	    <if test="keyword != null">
    			<include refid="criteria"></include>
    		</if>
     </select>
  • select 태그로 검색조건을 선택하여 입력
  • 검색버튼 클릭 시 keyword와 type값을 GET방식으로 가지고 이동
  • 페이지이동, 게시글페이지 이동했을 시도 검색이 유지될 수 있도록 검색어를 가지고 이동
          <!-- 검색창 -->
          <div class="d-flex justify-content-center mt-2">
            <div class="input-group input-group-static me-3" style="width: 8em">
              <label for="searchType" class="ms-0">검색방법</label>
              <select class="form-control" id="searchType">
                <!-- <option value="" th:selected="${pmk.cri.type} == ''"></option> -->
                <option value="T" th:selected="${pmk.cri.type} == 'T'">제목</option>
                <option value="C" th:selected="${pmk.cri.type} == 'C'">내용</option>
                <option value="W" th:selected="${pmk.cri.type} == 'W'">작성자</option>
                <option value="TC" th:selected="${pmk.cri.type} == 'TC'">제목 + 내용</option>
                <option value="TW" th:selected="${pmk.cri.type} == 'TW'">제목 + 작성자</option>
                <option value="TCW" th:selected="${pmk.cri.type} == 'TCW'">제목 + 내용 + 작성자</option>
              </select>
            </div>
            <div class="w-md-25 w-sm-50 input-group input-group-outline is-filled">
              <label class="form-label">search here...</label>
              <input type="text" id="searchKeyword" th:value="${pmk.cri.keyword}" class="form-control" />
              <button id="searchButton" class="btn btn-primary mb-0">검색</button>
            </div>
          </div>

    <script>
      const searchKeyword = document.getElementById('searchKeyword'); // 키워드 입력창의 값(내용)
      const searchButton = document.getElementById('searchButton'); // 검색 버튼
      const searchType = document.getElementById('searchType'); // 검색방법

      // 검색버튼을 눌렀을 때(이벤트 click) 키워드를 url에 추가해서 보내면 됨
      searchButton.addEventListener('click' , function() {
        let keyword = ''; // 키워드 변수 선언
        let type = ''; // type 변수 선언
        let currentKeyword = searchKeyword.value.trim(); // 공백제거키워드
        if (currentKeyword) { // 키워드가 있을 경우
          keyword = '&keyword=' + currentKeyword; // 키워드가 있을 경우에 '&keyword=키워드'
          type = '&type=' + searchType.value;
        }
        location.href = '/board/list?pageNum=1' + keyword + type; // 처음 키워드로 검색시 무조건 1페이지로 이동
      })
      
      // 페이지네이션의 a 태그들을 전부 자바스크립트 요청으로 바꾸기(키워드 추가)
      const pageLinks = document.querySelectorAll('ul.pagination .page-link');
      pageLinks.forEach(function(link){
        // 각각의 a태그를 클릭했을 때 => 함수실행
        link.addEventListener('click', pageControl);
      });

      // 제목 a 태그들을 선택해서 a태그 이동을 취소하고 키워드 추가해서 요청
      const getLinks = document.querySelectorAll('table .title');
       getLinks.forEach(function(link) {
        link.addEventListener('click', pageControl);
      })

        function pageControl(e) {
        e.preventDefault(); // a 태그 이동 중지
          let keyword = ''; // 키워드 변수 선언
          let type = ''; // type 변수 선언
          let currentKeyword = searchKeyword.value.trim(); // 공백제거키워드
          if (currentKeyword) { // 키워드가 있을 경우
          keyword = '&keyword=' + currentKeyword; // 키워드가 있을 경우에 '&keyword=키워드'
          type = '&type=' + searchType.value;
        }
          location.href = this.getAttribute('href') + keyword + type; // this = a태그, 현재 클릭한 a태그의 주소를 가져옴
        }
      
      

      </script>

참고(MyBatis sql, include문법)

https://kimvampa.tistory.com/176

참고(MyBatis choose, when, otherwise)

https://kimvampa.tistory.com/178

참고(MyBatis 동적SQL)

https://mybatis.org/mybatis-3/ko/dynamic-sql.html


댓글기능(1)

댓글을 저장할 DB Table만들기

  • 댓글은 게시글에 영향을 받기때문에 게시글에 외래키 연결
  • CASCADE는 연결된 게시글의 변화에 따라 같이 변함(게시글 삭제시 연결된 댓글 전부 삭제)

Mapper, Service 만들기

  • 댓글 DB 검색을 위한 Interface Mapper만들기
package com.myapp.bbs.dao;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.myapp.bbs.model.ReplyVO;

@Mapper
public interface ReplyMapper {

	public void enroll(ReplyVO reply); // 댓글 등록
	
	public List<ReplyVO> getReplyList(int reply_bno); // 댓글 리스트 불러오기
	
	public int modify(ReplyVO reply); // 댓글 수정
	
	public int delete(int reply_no); // 댓글 삭제

}
  • Mapper SQL문 작성
<?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 패키지 안의 replyMapper.java를 여기서 입력하겠다는 설정  -->
<mapper namespace="com.myapp.bbs.dao.ReplyMapper">

	<!-- 댓글 등록 -->
    <insert id="enroll" parameterType="ReplyVO"> <!-- application.properties에 설정을 하지 않았다면 parameterType="com.myapp.bbs.model.ReplyVO" 라고 적었야함 -->
		insert into reply(reply_bno, content, writer) 
		values (#{reply_bno}, #{content}, #{writer});
    </insert>
	
	<!-- 댓글 리스트 불러오기 -->
    <select id="getReplyList" resultType="ReplyVO">
     	select * 
     	from reply
     	where reply_bno = #{reply_bno}
    </select>
     
     <!-- 댓글 수정 -->
     <update id="modify" parameterType="ReplyVO">
     	update reply 
     	set  content = #{content}, update_at = now()
     	where reply_no = #{reply_no}
     </update>
     
     <!-- 댓글 삭제 -->
     <delete id="delete">
     	delete from reply 
     	where reply_no = #{reply_no}
     </delete>
     
</mapper>
  • 게시글 출력페이지(get.html)에 댓글 입력창 작성
              <!-- 댓글 입력 폼-->
              <div class="col-md-10 me-auto ms-auto">
                <div class="card card-body">
                  <div class="row">
                    <div class="col-3">
                      <div class="input-group input-group-outline mb-3">
                        <label class="form-label">글쓴이</label>
                        <input type="text" class="form-control" id="writer" required />
                      </div>
                      <div class="text-center">
                        <button id="reply-btn" class="btn bg-gradient-primary w-100 mb-0">댓글달기</button>
                      </div>
                    </div>
                    <div class="col-9">
                      <div class="input-group input-group-outline mb-0">
                        <div class="input-group input-group-dynamic">
                          <textarea id="content" class="form-control" rows="4" placeholder="댓글 내용을 적어주세요." required></textarea>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- 댓글리스트-->
            <div class="row mt-2">
              <div class="col-md-10 me-auto ms-auto">
                <div class="card card-plain">
                  <ul class="list-group" id="reply-list"></ul>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </main>

0개의 댓글