You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 新增UserOtpRepository查询方法:
public interface UserOtpRepository extends JpaRepository<UserOtp, Integer> {
    Optional<UserOtp> findFirstByUseridOrderByCreateDateDesc(Integer userId);
}
  1. 改造控制器代码,预加载所有用户的最新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";
}
  1. 页面取值:
<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:48:01