앞선 글에서 이어서 바로 카테고리로 검색하는 기능을 만들어보자.
테스트를 위해 상품 데이터베이스에 상품을 새로 추가하였다.
그 전에 검색어로 검색기능이 원래는 정확히 일치하여야 검색이 되었다면, 키워드로 검색이 가능하도록 해당 쿼리문을 고쳤다.
public List<Products> findByName(String name){
TypedQuery<Products> query = em.createQuery("SELECT u FROM Products u WHERE u.product_name LIKE :name", Products.class);
query.setParameter("name", "%" + name + "%");
List<Products> productsList = query.getResultList();
return productsList;
}
쿼리문을 다음과 같이 사용하게되면 name파라미터가 포함된 모든 상품들이 검색된다.
실험용 으로 검색시 다음과 같이 검색됨
유니폼으로 검색 시
이제 카테고리를 통한 검색이 가능하도록 만들어보자.
카테고리로 검색이 가능하도록 하기 위해 일단 카테고리를 데이터베이스에 모두 추가시켜놓았다.
카테고리의 title이 쿼리로 받은 카테고리를 포함하고 있다면, 포함하는 모든 id를 저장해서 보내줄 수 있도록 하였다. 즉, 의류를 선택했다면 의류로 분류된 카테고리의 id인 1,2,3,4가 모두 저장되어서 보내질 수 있도록 했다.
package com.shoppingmall.repository;
import com.shoppingmall.domain.Category;
import com.shoppingmall.domain.Products;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.List;
public class CategoryRepository {
@PersistenceContext
private final EntityManager em;
public CategoryRepository(EntityManager em) {
this.em = em;
}
public List<Integer> findIdByTitle(String title){
TypedQuery<Category> query = em.createQuery("SELECT u FROM Category u WHERE u.title LIKE :title", Category.class);
query.setParameter("title", "%" + title + "%");
List<Category> category = query.getResultList();
List<Integer> id = new ArrayList<>();
for(int i = 0; i<category.size(); i++){
id.add(category.get(i).getId());
}
return id;
}
}
보내진 id를 ProductService에서 사용하여 Products를 가져올 수 있도록 코드를 수정했다.
public List<Products> searchByCategory(String category){
List<Integer> id = categoryRepository.findIdByTitle(category);
List<Products> products = new ArrayList<>();
for(int categoryId : id){
products.addAll(productRepository.findByCategory(categoryId));
}
return products;
}
이제 컨트롤러가 받는 파라미터 값마다 다른 메소드가 실행되도록 해주면 우리가 원하는대로 실행이 될 것이다.
@GetMapping("/search")
public String search( @RequestParam(value = "query", required = false) String keyword,
@RequestParam(value = "category", required = false) String category,
@RequestParam(value = "sellerId", required = false) String sellerId,
Model model) {
// 여기서 query는 요청 파라미터의 이름입니다.
// 예를 들어, /search?query=검색어 형식으로 요청이 들어온다면,
// "검색어" 부분이 query 매개변수로 전달됩니다.
List<Products> products = new ArrayList<>();
if (category != null && !category.isEmpty()) {
products = productService.searchByCategory(category);
} else if (sellerId != null) {
products = productService.searchBySellerId(sellerId);
}else products = productService.searchByName(keyword);
model.addAttribute("products", products);
// 검색결과를 표시할 템플릿 이름을 반환합니다.
return "searchResult"; // search-result.html과 같은 템플릿 파일을 찾게 됩니다.
}
위와 같이 required = false를 통해 없으면 안 받아도 되도록 하고, 그 값이 null이면 사용하지 않는 쪽으로 가도록 했다.
마지막으로 js코드를 수정해서 category는 클릭 시, category 파라미터를 보내도록 하자.
function redirectSearchCategory(category) {
window.location.href = "/search?category=" + encodeURIComponent(category);
}
//코드 생략//
detailItem.addEventListener("click", () => {
// 사용자가 카테고리를 클릭했을 때 실행될 함수 호출
redirectSearchCategory(detail);
event.stopPropagation();
});
});
//코드 생략//
categoryItem.addEventListener("click", () => {
// 사용자가 카테고리를 클릭했을 때 실행될 함수 호출
redirectSearchCategory(ajaxCategory);
});
category_1depth.appendChild(categoryItem);
});
이제 테스트를 해보자!
상의 카테고리 클릭 시
의류 카테고리 클릭 시
다음과 같이 정상적으로 작동함을 확인할 수 있었다.
상품 데이터베이스는 제대로 작동되는 것 같으니 다음시간엔 장바구니 시스템을 구현해보도록 하자!