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

Spring Boot中如何用Transaction数据填充TransactionGroup的列表

问题修复:Spring Boot按日期分组展示交易页面为空

问题概述

我的Spring Boot应用中有Transaction表,需要按日期分组展示交易:仅显示有交易的日期,当日多条交易全部展示,无交易日期跳过。为此创建了TransactionGroup实体(包含LocalDate date和List<Transaction> transactions),但Thymeleaf页面展示为空。排查后确认问题出在:

  • 保存交易的Controller中调用的transactionGroup.setTransactions是空实现,且逻辑冗余
  • 展示交易的Controller仅实例化TransactionGroup,未从数据库获取交易并按日期分组
  • Thymeleaf模板存在变量引用错误

相关代码问题分析

1. TransactionGroup实体方法错误

当前setTransactions方法参数设计不合理且为空实现,完全无法填充交易列表:

// 错误的方法
public void setTransactions(String walletName, Double amount, LocalDate date, String note, ExpenseCategories expenseCategories, IncomeCategories incomeCategories) {
}

2. 保存交易Controller冗余代码

保存交易时不需要操作TransactionGroup,因为分组逻辑应该在查询阶段处理,而非保存阶段。

3. 展示交易Controller未实现分组逻辑

仅实例化空的TransactionGroup,未查询用户交易并按日期分组,且findDistinctIdByUserId无法获取完整交易数据。

4. Thymeleaf模板变量错误

循环交易时误用${transactions.amount}(循环变量是transaction,应为${transaction.amount});外层循环变量名应为列表类型(比如transactionGroups),而非单个transactionGroup。


修复步骤

步骤1:修正TransactionGroup实体

改为标准的getter/setter,添加构造方法方便分组时创建实例:

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class TransactionGroup {
    private LocalDate date;
    private List<Transaction> transactions;

    // 空构造
    public TransactionGroup() {}

    // 带日期的构造,初始化交易列表
    public TransactionGroup(LocalDate date) {
        this.date = date;
        this.transactions = new ArrayList<>();
    }

    // 标准getter/setter
    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public List<Transaction> getTransactions() {
        return transactions;
    }

    public void setTransactions(List<Transaction> transactions) {
        this.transactions = transactions;
    }

    // 新增添加单个交易的方法
    public void addTransaction(Transaction transaction) {
        this.transactions.add(transaction);
    }
}

步骤2:清理保存交易的Controller代码

删除无关的TransactionGroup逻辑,专注保存交易:

@PostMapping("/saveIncome/{walletId}")
public String saveIncome(@PathVariable(value = "walletId") long walletId, @Valid Transaction transaction, BindingResult result, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();

    Wallet wallet = walletService.getWalletById(walletId);

    transaction.setWallet(wallet);
    transaction.setUserId(userId);
    transaction.setWalletName(wallet.getWalletName());
    
    // 移除TransactionGroup相关代码
    transactionService.saveIncome(transaction, walletId, userId);
    return "redirect:/api/wallet/userWallet/balance/" + userId;
}

步骤3:修改展示交易的Controller,实现按日期分组

查询用户所有交易,按日期分组生成List<TransactionGroup>:

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@GetMapping("/userTransactions/{user_id}")
public String getUserTransactions(@PathVariable("user_id") long user_id, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();

    // 1. 查询用户所有交易(需确保transactionService有此方法,若没有则添加)
    List<Transaction> userTransactions = transactionService.findByUserId(user_id);

    // 2. 按交易日期分组
    Map<LocalDate, List<Transaction>> groupedByDate = userTransactions.stream()
            .collect(Collectors.groupingBy(Transaction::getDate));

    // 3. 转换为TransactionGroup列表
    List<TransactionGroup> transactionGroups = groupedByDate.entrySet().stream()
            .map(entry -> {
                TransactionGroup group = new TransactionGroup(entry.getKey());
                group.setTransactions(entry.getValue());
                return group;
            })
            .collect(Collectors.toList());

    // 4. 将分组后的列表放入Model
    model.addAttribute("transactionGroups", transactionGroups);
    model.addAttribute("userId", userId);
    return "transactions";
}

注意:需确保transactionService有findByUserId(long userId)方法,用于查询用户所有交易记录。

步骤4:修正Thymeleaf模板代码

修正循环变量名和交易属性引用:

<!-- 外层循环遍历分组列表 -->
<div th:each="group : ${transactionGroups}">
    <h1 th:text="${group.date}" />

    <!-- 内层循环遍历当日交易 -->
    <div th:each="transaction : ${group.transactions}">
        <h2>Amount: <span th:text="${transaction.amount}"></span></h2><br>
        <h2>Note: <span th:text="${transaction.note}"></span></h2><br>
        <h2>Wallet name: <span th:text="${transaction.walletName}"></span></h2><br>
        <h2>Expense Category: <span th:text="${transaction.expenseCategories}"></span></h2><br>
        <h2>IncomeCategory: <span th:text="${transaction.incomeCategories}"></span></h2>
    </div>
</div>

内容的提问来源于stack exchange,提问作者Frosty Nah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:31:06