Spring Boot项目一对多关联下如何查询子表最新otp字段并在页面展示
实现方案
你当前的问题是直接输出了User实体关联的UserOtp集合对象,默认调用了集合的toString()方法,才会展示全量集合内容。可以通过以下三种方案实现需求,推荐优先使用第一种或第三种:
方案1:实体类新增便捷方法(代码最简洁)
在Users实体类中新增获取最新OTP的工具方法,不需要修改原有业务逻辑:
// 放在Users类的Getter/Setter区域 public UserOtp getLatestUserOtp() { if (this.userOtp == null || this.userOtp.isEmpty()) { return null; } // 按OTP创建时间倒序排序,取第一条即为最新记录 return userOtp.stream() .sorted((o1, o2) -> o2.getCreateDate().compareTo(o1.getCreateDate())) .findFirst() .orElse(null); }
修改Thymeleaf页面的对应列代码即可:
<!-- OTP列 --> <td th:text="${user.latestUserOtp?.otp}">无OTP</td> <!-- OTP生成时间列(原来的写法取的是用户创建时间,需要修改) --> <td th:text="${user.latestUserOtp?.createDate}">无生成时间</td> <!-- 用户更新时间保持不变,注意属性是小驼峰写法 --> <td th:text="${user.updateDate}">July 12, 2012 12:13:00 PM</td>
代码中的?.是空安全运算符,避免用户没有OTP记录时抛出空指针异常。
方案2:直接在Thymeleaf页面处理(无需修改后端代码)
如果不想修改后端代码,可以直接在页面用SpEL表达式对集合排序后取最新值,不推荐生产环境使用,性能略低:
<td th:text="${#lists.sort(user.userOtp, (o1,o2) -> o2.createDate.compareTo(o1.createDate))[0]?.otp}">6566</td>
方案3:优化查询逻辑(性能最优)
如果数据量较大,上述两种方案需要加载每个用户的全量OTP记录会浪费性能,可以单独查询每个用户的最新OTP:
- 新增
UserOtpRepository查询方法:
public interface UserOtpRepository extends JpaRepository<UserOtp, Integer> { Optional<UserOtp> findFirstByUseridOrderByCreateDateDesc(Integer userId); }
- 改造控制器代码,预加载所有用户的最新OTP:
@RequestMapping("/admin/index") public String Login(Model model) { long countUsers = userRepositoryService.countUsers(); List<Users> users = userRepositoryService.getUsers(); // 预存所有用户的最新OTP Map<Integer, UserOtp> latestOtpMap = new HashMap<>(); for (Users user : users) { latestOtpMap.put(user.getUserid(), userOtpRepository.findFirstByUseridOrderByCreateDateDesc(user.getUserid()) .orElse(null)); } model.addAttribute("usersCount", countUsers); model.addAttribute("users", users); model.addAttribute("latestOtpMap", latestOtpMap); return "/admin/index"; }
- 页面取值:
<td th:text="${latestOtpMap[user.userid]?.otp}">无OTP</td> <td th:text="${latestOtpMap[user.userid]?.createDate}">无生成时间</td>
注意:原页面中
${user.CreateDate}、${user.UpdateDate}写法错误,Java属性为小驼峰命名,需要改为${user.createDate}、${user.updateDate}否则会抛出属性找不到异常。
内容的提问来源于stack exchange,提问作者Shiraji
相关产品推荐
相关产品推荐

