如何使用Thymeleaf获取Employee实体Review集合的整数平均评分并插入表格
解决方案
第一步:实现平均分数计算逻辑
根据你的业务场景可以选以下两种常用实现:
方式1:在Employee实体类新增临时计算方法(适合数据量小的简单场景)
加@Transient注解避免JPA将该字段持久化到数据库:
@Entity public class Employee extends AbstractBaseEntity { @OneToMany( mappedBy = "employee", cascade = CascadeType.MERGE, fetch = FetchType.LAZY) private List<Review> reviews; // 新增平均分计算方法 @Transient public Integer getAverageGrade() { if (reviews == null || reviews.isEmpty()) { return 0; // 无评价时的默认值,可按需调整为null或其他值 } double avg = reviews.stream() .filter(review -> review.getGrade() != null) // 过滤空的grade字段 .mapToInt(Review::getGrade) .average() .orElse(0); // 示例为四舍五入取整,需要向下取整直接写(int)avg即可 return (int) Math.round(avg); } }
注意:使用该方式查询Employee时,需要用JOIN FETCH关联抓取reviews字段,避免触发懒加载异常,不要随意把fetch策略改成EAGER,会影响其他查询性能。
方式2:Repository层通过JPQL直接计算(性能更好,适合数据量大的场景)
直接在数据库层面完成计算,不需要把所有Review加载到内存:
// 在EmployeeRepository中新增查询方法 @Query("SELECT e, COALESCE(ROUND(AVG(r.grade)), 0) FROM Employee e LEFT JOIN e.reviews r GROUP BY e") List<Object[]> findAllWithAverageGrade();
查询返回的数组中,第一个元素为Employee对象,第二个为已计算好的平均整数值,你可以按需封装为DTO后传给前端。
第二步:Controller层传递数据到Thymeleaf
以方式1为例,Controller代码示例:
@GetMapping("/employees") public String getEmployeeList(Model model) { // 查询时注意关联抓取reviews,避免懒加载异常 List<Employee> employees = employeeRepository.findAllWithReviews(); model.addAttribute("employees", employees); return "employee-list"; }
第三步:Thymeleaf模板渲染表格
<table> <thead> <tr> <th>员工ID</th> <th>员工姓名</th> <!-- 其他需要展示的员工字段 --> <th>评价平均分</th> </tr> </thead> <tbody> <tr th:each="emp : ${employees}"> <td th:text="${emp.id}"></td> <td th:text="${emp.name}"></td> <!-- 其他字段渲染 --> <td th:text="${emp.averageGrade}"></td> </tr> </tbody> </table>
如果使用方式2的DTO结构,把对应平均分的属性名替换即可。
内容的提问来源于stack exchange,提问作者user15599360
相关产品推荐
相关产品推荐

