스프링 부트 카테고리 별 조회 - seupeuling buteu kategoli byeol johoe

글 검색 기능을 추가해보겠습니다. 제목,작성자,내용에 검색어가 포함된 글들만 리스트로 보여줄 예정입니다.

BoardController

    @GetMapping("/board/search")
    public String search(@RequestParam(value="keyword") String keyword, Model model) {
        model.addAttribute("postList", boardService.searchPosts(keyword));
        return "board/list.html";
    }

여러분도 아시다시피 GET방식은 'localhost:8080?keyword=abcd' 로 값이 넘어오죠. REST API처럼 구현하고 싶은데 저는 실패를 했습니다.. 아무튼 저렇게 넘어온 값은 @RequestParam으로 받아올 수 있습니다. 받아온 keyword는 서비스로 넘겨줍니다.

BoardService

    @Transactional
    public List<BoardListDto> searchPosts(String keyword) {
        return boardRepository.findAllSearch(keyword).stream()
                .map(BoardListDto::new)
                .collect(Collectors.toList());
    }

findAllSearch(keyword)한 값을 리스트로 반환을 해주죠. Repository에서는 어떤 쿼리로 검색을 반환해줄까요??

BoardRepository

    @Query(value = "SELECT b FROM Board b WHERE b.title LIKE %:keyword% OR b.content LIKE %:keyword% OR b.author LIKE %:keyword%"
    )
    List<Board> findAllSearch(String keyword);

SQL문에서는 A라는 문자열에 B라는 문자열이 포함되었는지를 LIKE를 통해서 필터링을 할 수 있습니다. %:keyword%의 경우에는 keyword라는 변수가 포함된 그런 컬럼값을 리턴하라는거죠. 저는 제목,작성자,내용 전부를 살펴볼 계획이었으니 OR로 계속 묶어줬습니다. 

자 이렇게 해주시면 검색 기능도 마무리가 된답니다. 

GoodsFrontController.java의 doProcess()의 주소비교 후 처리부분에 코드 추가

1
2
3
4
5
6
7
8
9
10
11
12
System.out.println("--------------@ 주소 비교후 처리 @-------------");
Action action = null;
ActionForward forward = null;

if(command.equals("/GoodsList.go")){

System.out.println("C: /GoodsList.go 호출");

action = new GoodsListAction();
try { forward = action.execute(request, response);
} catch (Exception e) { e.printStackTrace(); }
}

GoodsListAction.java 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class GoodsListAction implements Action {

@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("M : GoodsListAction의 execute() 호출");

request.setCharacterEncoding("UTF-8");


String item = request.getParameter("item");
System.out.println("카테고리 : "+item);
if(item == null){
item = "all";
}


GoodsDAO gdao = new GoodsDAO();

List<GoodsDTO> goodsList = gdao.GoodsList(item);


System.out.println("M : "+goodsList);


request.setAttribute("goodsList", goodsList);


ActionForward forward = new ActionForward();
forward.setPath("./goods/goods_list.jsp");
forward.setRedirect(false);
return forward;
}

}

GoodsDAO.java 생성 후 GoodsListAll()메서드 코드 추가

  • 상품전제목록 조회 -> 이거 대신 카테고리별 상품목록조회 GoodsList(String item)메서드 사용
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    public List<GoodsDTO> GoodsListAll() {
    List<GoodsDTO> goodsList = new ArrayList<GoodsDTO>();
    try {
    getCon();
    sql = "select * from itwill_goods";
    pstmt = con.prepareStatement(sql);
    rs = pstmt.executeQuery();
    while(rs.next()){
    GoodsDTO gdto = new GoodsDTO();
    gdto.setGno(rs.getInt("gno"));
    gdto.setCategory(rs.getString("category"));
    gdto.setName(rs.getString("name"));
    gdto.setPrice(rs.getInt("price"));
    gdto.setColor(rs.getString("color"));

    gdto.setAmount(rs.getInt("amount"));
    gdto.setSize(rs.getString("size"));
    gdto.setContent(rs.getString("content"));
    gdto.setImage(rs.getString("image"));
    gdto.setBest(rs.getInt("best"));

    gdto.setDate(rs.getDate("date"));

    goodsList.add(gdto);
    }
    System.out.println("DAO : 상품목록 모두 저장완료! "+goodsList);
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    closeDB();
    }
    return goodsList;
    }

GoodsDAO.java 생성 후 GoodsList(String item)메서드 코드 추가

  • item에 따라 쿼리구문이 달라진다.
    • item이 각 카테고리명인 경우 sql = "select * from itwill_goods where category=?";
    • item == null인 경우 sql = "select * from itwill_goods";
    • item == best인 경우 sql = "select * from itwill_goods where best=?";
    • 따라서 String대신 StringBuffer를 써보자.
      • 참고 : StringBuffer와 String의 차이점
  • 아래 세가지 방법으로 StringBuffer를 String으로 나타낼수있다
    • pstmt = con.prepareStatement(SQL.toString());
    • pstmt = con.prepareStatement(SQL+””);
      • +는 덧셈 또는 String타입으로 바꿔주는 두 가지 기능이 있다.
      • 뒤에 + 공백이 붙으면 +가 두번째 기능을 해서 String으로 데이터 타입을 바꿔준다. 기억할 것!
    • pstmt = con.prepareStatement(String.valueOf(SQL)); //object에 담아서 거기서 string으로 꺼낸다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

public List<GoodsDTO> GoodsList(String item) {
List<GoodsDTO> goodsList = new ArrayList<GoodsDTO>();

StringBuffer SQL = new StringBuffer();

try {
getCon();
SQL.append("select * from itwill_goods");

if(item.equals("all")){
}else if(item.equals("best")){
SQL.append(" where best=?");
}else{
SQL.append(" where category=?");
}


pstmt = con.prepareStatement(SQL.toString());



if(item.equals("all")){
}else if(item.equals("best")){
pstmt.setInt(1, 1);
}else{
pstmt.setString(1, item);
}

rs = pstmt.executeQuery();
while(rs.next()){
GoodsDTO gdto = new GoodsDTO();
gdto.setGno(rs.getInt("gno"));
gdto.setCategory(rs.getString("category"));
gdto.setName(rs.getString("name"));
gdto.setPrice(rs.getInt("price"));
gdto.setColor(rs.getString("color"));

gdto.setAmount(rs.getInt("amount"));
gdto.setSize(rs.getString("size"));
gdto.setContent(rs.getString("content"));
gdto.setImage(rs.getString("image"));
gdto.setBest(rs.getInt("best"));

gdto.setDate(rs.getDate("date"));

goodsList.add(gdto);
}
System.out.println("DAO : 상품목록 모두 저장완료! "+goodsList);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeDB();
}
return goodsList;
}

goods_list.jsp 생성

  • 제품의 총 개수를 카테고리수 만큼만 출력하고 그 이상인 경우 다음 row로 출력하려면 어떻게 하면 될까?
    • 필요한 정보 : total개수, row개수, col개수
    • 예를 들어 total 16개 col은 8개 => 필요한 row는 2개
    • 예를 들어 total 17개 col은 8개 => 필요한 row는 3개
    • 내코드
      1
      2
      int result = goodsCnt%col;
      int row = result == 0 ? result:result+1;
    • 강사님코드
      1
      int row = (goodsCnt/col) + (goodsCnt%col>0? 1:0);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 <%
// request영역에서 정보를 꺼내서 테이블에 추가
List<GoodsDTO> goodsList = (List<GoodsDTO>)request.getAttribute("goodsList"); //object->list타입 캐스팅

%>
<fieldset>
<legend>상품목록</legend>
<table border="1">
<tr>
<td><input type="button" class="btnCate" value="전체"
onclick="location.href='./GoodsList.go'"></td>
<td><input type="button" class="btnCate" value="인기상품(Best)"
onclick="location.href='./GoodsList.go?item=best'"></td>
<td><input type="button" class="btnCate" value="아우터"
onclick="location.href='./GoodsList.go?item=outwear'"></td>
<td><input type="button" class="btnCate" value="정장"
onclick="location.href='./GoodsList.go?item=fulldress'"></td>
<td><input type="button" class="btnCate" value="티셔츠"
onclick="location.href='./GoodsList.go?item=Tshirts'"></td>
<td><input type="button" class="btnCate" value="셔츠"
onclick="location.href='./GoodsList.go?item=shirts'"></td>
<td><input type="button" class="btnCate" value="바지"
onclick="location.href='./GoodsList.go?item=pants'"></td>
<td><input type="button" class="btnCate" value="신발"
onclick="location.href='./GoodsList.go?item=shoes'"></td>
</tr>
<%
//필요한 정보 : total개수, row개수, col개수
//total 16col8개 => 필요한 row는 2개
//total 17개 col은 8개 => 필요한 row는 3개
int goodsCnt = goodsList.size();
int col = 8;
//내코드
/* int result = goodsCnt%col;
int row = result == 0 ? result:result+1; */
//강사님코드
int row = (goodsCnt/col) + (goodsCnt%col>0? 1:0);

int checkNum = 0; //출력개수를 총개수보다 많지 않게 처리하는 값을 저장하는 변수

for(int i=0; i<row; i++){
%>
<tr>
<%
for(int j=0; j<col; j++){
//List 한칸의 정보 -> GoodsDTO 객체 하나로 이동
GoodsDTO gdto = goodsList.get(checkNum);
%>
<td>
<img src="./upload/<%=gdto.getImage().split(",")[0]%>" height="100"><br>
<a href= "./GoodsDetail.go?gno=<%=gdto.getGno()%>"><%=gdto.getName() %></a><br>
가격 : <%=gdto.getPrice() %><br>
<input type="button" class="btn" value="장바구니"
onclick="location.href='./AdminGoodsDeleteAction.ag?gno=<%=gdto.getGno()%>'">
</td>
<%
checkNum++;
if(checkNum == goodsCnt) break;
}
%>
</tr>
<%
} //end of for-i반복문
%>
</table>
</fieldset>