Spring Data JPA如何编写按分类查询书籍的Query?原有查询无数据如何解决
问题核心错误点
- 原生SQL关联条件错误:你写的JOIN条件为
b.name = c.id,把书籍名称和分类ID做关联,逻辑完全不成立。Book表关联Category的外键是categoryid字段,需要用该字段关联Category表的id - 变量命名逻辑混乱:Controller里把查到的书籍列表存到了名为
category的Model属性里,Thymeleaf遍历的时候又把每个Book对象当成Category使用,展示逻辑完全错位 - 路径映射不匹配:Controller的GetMapping路径是
/{category},但Thymeleaf里跳转的路径是/category/{id},路径不匹配会触发404错误
修复方案
1. 修正BookRepo的查询语句
提供三种可选方案,优先推荐JPA自动生成查询的写法:
方案1:方法名自动生成查询(无需手动写SQL)
// Spring Data JPA会自动根据方法名生成符合规则的查询语句 List<Book> findByCategory_Id(Integer categoryId);
方案2:JPQL查询
@Query("SELECT b FROM Book b WHERE b.category.id = :categoryId") List<Book> findBookByCategory(@Param("categoryId") Integer categoryId);
方案3:修正后的原生SQL查询
@Query(value = "SELECT b.* FROM book b INNER JOIN category c on b.categoryid = c.id WHERE c.id = ?1", nativeQuery = true) List<Book> findBookByCategory(Integer categoryId);
2. 修正Controller代码
// 路径改为和Thymeleaf跳转匹配的/category前缀 @GetMapping("/category/{categoryId}") public String getBookByCategory(@PathVariable("categoryId") Integer categoryId, Model model, HttpSession session) { List<Book> bookList = bookService.findBookByCategory(categoryId); if(bookList == null || bookList.isEmpty()) { session.setAttribute("message", new MessageResponse("Không có Sách","danger")); } // 分别存储分类下的书籍列表,以及全部分类列表(渲染分类菜单需要查询所有分类) model.addAttribute("bookList", bookList); // 补充查询所有分类的逻辑,用于渲染左侧分类菜单 List<Category> categoryList = categoryService.findAll(); model.addAttribute("categoryList", categoryList); return "home/category"; }
3. 修正Thymeleaf视图代码
<!-- 渲染分类菜单部分 --> <h4 class="text-uppercase font-weight-bold mb-3">Thể Loại</h4> <div class="mt-2 mb-2 pl-2 "> <div class="custom-control" th:each="category : ${categoryList}" th:value="${category.id}"> <h5> <a class="btn btn-info popovers" th:href="@{/category/{id}(id=${category.id})}" >[[${category.name}]]</a> </h5> </div> </div> <!-- 渲染当前分类下的书籍列表 --> <div th:if="${!bookList.isEmpty()}"> <div th:each="book : ${bookList}"> <p>书籍名称:[[${book.name}]]</p> <p>书籍描述:[[${book.description}]]</p> </div> </div> <p th:if="${bookList.isEmpty()}" class="text-danger">暂无该分类下的书籍</p>
内容的提问来源于stack exchange,提问作者quanghuy
相关产品推荐
相关产品推荐

