Spring JPA如何统计外键关联数量实现作者作品数列展示
Java Spring 书籍整理应用作品数展示实现方案
1 先修正现有代码的已知问题
你当前的代码存在几处基础错误,需要先修复:
- BookTitleRepository 接口名错误定义为了
AutherRepository,和作者Repository重名 - BookService 中的
BookTitleRepository没有加@Autowired注解,无法被Spring注入 - BookService 中的统计方法只有定义没有实现逻辑
修正后的代码如下
AutherRepository.java (无需改动)
@Repository public interface AutherRepository extends JpaRepository <AutherEntity, Long> { }
BookTitleRepository.java
@Repository // 修正接口名 public interface BookTitleRepository extends JpaRepository <BookTitleEntity, Long> { // 适配Spring Data JPA命名规则,调整方法名(如果实体类字段为auther_id可搭配@Column注解映射) long countByAutherId(long autherId); }
BookService.java
@Service @Transactional public class BookService { @Autowired private AutherRepository autherRepository; // 补全注入注解 @Autowired private BookTitleRepository bookTitleRepository; // 实现按作者ID统计书籍数量的方法 public Long countBookByAutherId(long autherId) { return bookTitleRepository.countByAutherId(autherId); } // 新增封装方法:获取所有作者及对应作品数,供控制层调用 public List<Map<String, Object>> getAutherListWithBookCount() { List<AutherEntity> autherList = autherRepository.findAll(); List<Map<String, Object>> result = new ArrayList<>(); for (AutherEntity auther : autherList) { Map<String, Object> item = new HashMap<>(); item.put("autherId", auther.getAutherId()); item.put("autherName", auther.getAutherName()); item.put("birthplace", auther.getBirthplace()); item.put("bookCount", countBookByAutherId(auther.getAutherId())); result.add(item); } return result; } }
2 新增控制层代码
你可以根据需求选择返回模板页面或者JSON数据,这里以常用的Thymeleaf模板为例:
@Controller public class BookController { @Autowired private BookService bookService; @GetMapping("/authorBookList") public String getAuthorList(Model model) { model.addAttribute("authorList", bookService.getAutherListWithBookCount()); return "authorBookList"; } }
3 前端HTML表格渲染
在模板文件authorBookList.html中编写表格代码,直接渲染带作品数的作者列表:
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse;"> <thead> <tr style="background-color: #f5f5f5;"> <th>作者ID</th> <th>作者姓名</th> <th>出生地</th> <th>作品数量</th> </tr> </thead> <tbody> <tr th:each="author : ${authorList}"> <td th:text="${author.autherId}"></td> <td th:text="${author.autherName}"></td> <td th:text="${author.birthplace}"></td> <td th:text="${author.bookCount}"></td> </tr> </tbody> </table>
可选性能优化
如果数据量较大,循环查询数据库会影响性能,可以直接在AutherRepository中写JPQL一次性关联查询,减少数据库交互次数:
@Query("SELECT a.autherId, a.autherName, a.birthplace, COUNT(b.titleId) FROM AutherEntity a LEFT JOIN BookTitleEntity b ON a.autherId = b.autherId GROUP BY a.autherId") List<Object[]> getAuthorWithBookCountOneQuery();
然后在BookService中直接调用该方法封装结果即可。
内容的提问来源于stack exchange,提问作者Aledun
相关产品推荐
相关产品推荐

