Criteria 에 검색키워드만 추가하기 + getter,setter,toString 자동생성

/* 검색어 키워드 */
private String keyword;

 

RecipeMapper 에 keyword도 추가 됨!

public List<RecipeVO> getListPaging(Criteria criteria);  //Criteria 객체로 keyword 입력되니까

 

 

[ mapper.xml ]

<select id="getListPaging" resultType="RecipeVO">
    
      select * from (
              select id, title, writer, ingredient, registerdate, updateDate  
              from recipe 
           
              <if test="keyword != null">                // 키워드가 있으면 concat함수가 실행
               where title like concat('%',#{keyword},'%')   
              </if>

              order by id desc
              ) as T1
      limit #{skip},#{amount}
   
</select>

* concat('%', #{keyword}, '%')  문자열 합침 %keyword%

 

 

 

게시물 총 개수에도 if절 넣기

<!-- 게시물 총 개수 -->
<select id="getTotalPost" resultType="int">
    
      select count(*) from recipe
      <if test="keyword != null"> 
         where title like concat('%',#{keyword},'%')   
      </if>
    
</select>

☆ 키워드가 getTotalPost에 전달되어야 함.

 

[ RecipeMapper ]

public int getTotalPost(Criteria criteria);

키워드가 포함된 criteria 객체가 있어야 if절에 키워드 전달가능.

 

 

-> mapper가 수정됐으면 줄줄이 수정해야함 service, serviceImpl, controller

 

service는 mapper와 똑같이 수정돼야함

 

[ serviceImpl ] 

@Override
public int getTotalPost(Criteria criteria) {
   return recipeMapper.getTotalPost(criteria);
}

 

controller에 에러 수정하기.

 

 

 


검색 view 화면

<!-- 테이블 끝 -->
<!-- 검색창 -->
    <div class="d-flex justify-content-center mt-2">
        <div class="w-md-25 w-sm-50 input-group input-group-outline is-filled">
            <input type="text" id="searchKeyword" th:value="${pmk.criteria.keyword}" class="form-control" placeholder="search here.." />
            <button id="searchButton" class="btn btn-primary mb-0">검색</button>
        </div>
    </div>
<!-- 페이지네이션 시작  -->

 

 검색어 입력할때 후 검색버튼 누르면 주소이동하도록 자바스크립트로 설정하기!!

 

JS        

 <script>
    const searchKeyword = document.getElementById('searchKeyword'); //검색창의 input 값내용
    const searchButton = document.getElementById('searchButton'); //검색버튼

    /* 검색버튼 눌렀을때 (이벤트 'click') 키워드를 url에 추가해서 보내기 */
    searchButton.addEventListener('click', function(){
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        if(공백제거키워드) keyword = '&keyword=' + 공백제거키워드; //키워드가 있으면 $keyword=키워드

        location.href='/recipe/board/list?pageNum=1' + keyword; //처음 키워드 검색시 무조건 1페이지 보여줌

    });
</script>

 공백제거된 키워드가 있으면 keyword => &keyword=키워드

 

 

 

첫번째 문제.

키워드 검색 후 페이지 버튼을 누르면 다시 처음으로 돌아가서 모든 게시글이 나온다.

 

+ 스크립트에 추가

 페이지네이션 a태그들을 전부 Js 요청으로 바꾸기 (키워드 추가)

const pageLinks = document.querySelectorAll('ul.pagination .page-link')  // 페이지네이션 a태그들

pageLinks.forEach(function(link){       // a태그가 한개씩 link로 들어감
    // 각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',function(e){
        e.preventDefault();   // a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지)
        let keyword = '';  
        let 공백제거키워드 = searchKeyword.value.trim();
        if(공백제거키워드) keyword = '&keyword=' + 공백제거키워드; //키워드가 있으면 &keyword=키워드

        location.href= this.getAttribute('href') + keyword;  // this는 클릭한 a태그 주소
    });
});
 
a태그 클릭시 주소 이동 기능을 제거하고  e.preventDefault(); 
 
주소를 '이동주소 + 키워드' 로 수정하기  location.href= this.getAttribute('href') + keyword; 
 
 

=> 그렇게 하면 키워드 검색 후 페이지 클릭 할때 검색키워드만 페이지 이동이 됨.

 

 

두번째 문제.

게시글 페이지에서 목록 버튼을 눌렀을때 검색 한 키워드가 풀려버리고 다시 처음부터 돌아간다.

 

 

 

마우스를 갖다대보니 키워드와 페이지 번호 가 없어서 처음부터 돌아감

 

 

해결방법은??

게시판 목록에서 타이틀에 키워드와 페이지 번호를 넘겨주기!

 

4 페이지에서 타이틀 클릭후 목록으로갔을때 
1. 그대로 4페이지

2. 그대로 키워드 있도록

 

 

 

[ recipe_list.html ]

 

타이틀에 class="title" 넣고 js로 설정하기

<a class="title" th:href="@{/recipe/board/get(id=${board.id})}">
      <span class="text-secondary text-xs" th:text="${board.title}"></span>
</a>
                               
 const getLinks = document.querySelectorAll('table .title');
 getLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
          //각각의 a태그를 클릭 시 함수실행
          link.addEventListener('click',function(e){
                e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지)
                let keyword = ''; //키워드 변수 선언
                let 공백제거키워드 = searchKeyword.value.trim();
                if(공백제거키워드) keyword = '&keyword=' + 공백제거키워드; 
                let pageNum = document.querySelector('.active a').textContent;  //현재 페이지 active 의 a태그
                location.href= this.getAttribute('href') + keyword + '&pageNum=' + pageNum;
         });
 });

 

 

pageNum이 이상하게 넘어간다...

.active a태그 코드도 확인해봤고 오류,에러는 안나고.. 뭘까

 

('.active a').textContent 로 하면 '못난이 상점'이 나와서 다르게 해봤음

 

해결!!

 let pageNum = '[[${criteria.pageNum}]]';

이렇게 고치면  클릭했던 페이지는 나오는데 %20 이 나온다..???

파라미터에 공백이 생기면 %20 이 나오나보다

'&pageNum  ='  에서 공백없이 '&pageNum= ' 을 썼더니 파라미터에 잘 전달된 것을 확인 할 수 있다~~


게시글 조회 html 

[ get.html ]

<div class="card-footer bg-white text-center pt-0 px-lg-2 px-1">
    <a th:href="@{/recipe/board/list} +
         '?pageNum=__${criteria.pageNum}__'
         class="btn btn-success page">목록</a>
    <a th:href="@{/recipe/board/modify(id=${board.id})}" class="btn btn-secondary">수정</a>
    <button class="btn btn-danger" onclick="deleteConfirm();">삭제</button>
</div>

pageNum을 넣어서 

클릭했던 페이지 그대로 돌아가기. (4페이지 -> 4페이지)

 

 

 

 

게시글 클릭했을때 오류

 

 

[RecipeController]

게시글 조회 하는 get매핑에서 criteria를 안넘겨줬다

Criteria criteria 객체를 추가하자!!

//게시판 글 조회
@GetMapping("/get")
public String recipePageGet(@RequestParam("id") int id, Model model,Criteria criteria) {
   model.addAttribute("board", recipeService.getPage(id));
   model.addAttribute("criteria", criteria);
   return "get";
}

 

 

게시글 수정 할때도 criteria 객체 넘겨주기

//게시판 글 수정
@GetMapping("/modify")
public String recipeModifyGet(@RequestParam("id") int id, Model model,Criteria criteria) {
    model.addAttribute("board", recipeService.getPage(id));
    model.addAttribute("criteria", criteria);
    return "modify";
}

 

 


 

keyword도 같이 넣었더니 목록에서 null값이 나와서 수정버튼에 넣고 js로 설정해줬더니 됨.

<a th:href="@{/recipe/board/modify(id=${board.id})} + '&pageNum=__${criteria.pageNum}__'" class="btn btn-secondary page">수정</a>

※  ? & 구분잘하기 

id가 이미 ?이라서 pageNum은 &

 

 

 

- 목록과 수정 버튼에 class=page 추가하기

 

  JS

키워드 검색 후 목록, 수정버튼 클릭 후 되돌아올때 키워드 그대로 있도록

const links = document.querySelectorAll('a.page');  // a태그안의 class라서 붙이기 (주의!!)
links .forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',function(e){
        e.preventDefault(); //a태그의 이동 요청이 취소됨.
        let keyword = '[[${criteria.keyword}]]';

        location.href= this.getAttribute('href')  + '&keyword=' + keyword; 
    });
});

 

 

= 키워드도 그대로 페이지도 그대로 돌아감.

 

 

수정페이지에서 수정 취소 클릭시 돌아갈때도 그대로 있도록 하려면???

<div class="text-center">
    <a th:href="@{/recipe/board/list}
       +'?pageNum=__${criteria.pageNum}__&keyword=__${criteria.keyword}__'"   
       class="btn btn-lg btn-danger">수정 취소</a>
    <button type="submit" class="btn btn-lg bg-primary">수정하기</button>
</div>

 

pageNum 이랑 keyword를 넣어주기

반응형
LIST

+ Recent posts