如何阻止Thymeleaf覆盖视图数据导致Spring Boot JDBC查询结果重复展示
问题根因
你的代码问题出在Controller层的数据传递逻辑,并非前端渲染问题:
- 你在while循环遍历ResultSet时,每次都调用
model.addAttribute("Title", xxx),同一个key多次赋值会覆盖之前的值,所以循环结束后model里的Title、Category、Author全是最后一行数据的对应值 - 前端你循环的是长度为2的IDList,每一次循环都拿model里全局的那组最后一行的属性,所以就出现了两次第二行的内容
修复方案
步骤1:创建Quiz实体类封装每行数据
// 新建Quiz.java POJO类 public class Quiz { private String id; private String title; private String category; private Integer author; // 全参构造方法 public Quiz(String id, String title, String category, Integer author) { this.id = id; this.title = title; this.category = category; this.author = author; } // 补全所有属性的getter方法,Thymeleaf需要通过getter读取属性 public String getId() {return id;} public String getTitle() {return title;} public String getCategory() {return category;} public Integer getAuthor() {return author;} }
步骤2:修改Controller逻辑,传递对象列表
@GetMapping(path="/home") public String HomeString(Model model){ ArrayList<Quiz> quizList = new ArrayList<>(); Connection dbConnection = null; Statement st = null; ResultSet rs = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); dbConnection = DriverManager.getConnection("...");//替换为你的数据库连接信息 st = dbConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); st.executeUpdate("use quiz;"); rs = st.executeQuery("SELECT * FROM quiz;"); while (rs.next()) { // 每一行数据封装为一个Quiz对象 Quiz quiz = new Quiz( rs.getString(1), rs.getString(2), rs.getString(4), rs.getInt(3) ); quizList.add(quiz); } // 把整个Quiz列表传到前端 model.addAttribute("quizList", quizList); } catch (Exception e) { e.printStackTrace(); } finally { // 手动关闭资源避免泄露 try {if(rs!=null) rs.close();} catch (Exception e) {} try {if(st!=null) st.close();} catch (Exception e) {} try {if(dbConnection!=null) dbConnection.close();} catch (Exception e) {} } return "Homepage";//替换为你的视图名称 }
步骤3:修改Thymeleaf表格逻辑,循环对象列表
<table id="allQuizzesTable" class="table table-bordered table-hover" style="width: 100%"> <thead> <tr> <td>Quiz ID</td> <td>Title</td> <td>Category</td> <td>Created by </td> </tr> </thead> <tbody> <!-- 循环quizList,每一项别名为quiz --> <tr th:each="quiz : ${quizList}"> <td th:text="${quiz.id}"></td> <td th:text="${quiz.title}"></td> <td th:text="${quiz.category}"></td> <td th:text="${quiz.author}"></td> </tr> </tbody> </table>
优化建议
如果不想手动管理JDBC连接、资源关闭逻辑,可以直接使用Spring Boot自带的JdbcTemplate组件操作原生SQL,代码会更简洁。
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

