如何正确使用PrimeFaces可编辑数据表更新数据库数据
问题描述
实现PrimeFaces可编辑数据表的行编辑更新功能时,页面弹出Update has done成功提示,但数据库对应记录未实际更新。目前数据读取功能正常,参考官方示例对接自有数据库时出现该问题,原有业务代码如下:
public static void edit(Config f, int id){ Connection connection = null; try { DB_connection2 obj_DB_connection = new DB_connection2(); connection = obj_DB_connection.get_connection(); PreparedStatement ps = connection.prepareStatement("update config set description=?,valeur=? where id='"+id+""); ps.setString(1, f.getDescription()); ps.setInt(2, f.getValeur()); ps.executeUpdate(); }catch(Exception e){ e.printStackTrace(); } } public void onRowEdit(RowEditEvent<Config> event) { Config f = new Config(); f.setDescription(String.valueOf(event.getObject().getDescription())); f.setValeur((event.getObject().getValeur())); edit( f, event.getObject().getId()); FacesMessage msg = new FacesMessage("Update has done", String.valueOf(event.getObject().getId())); FacesContext.getCurrentInstance().addMessage(null, msg); }
问题根因
代码存在5个核心问题,导致更新不生效、提示与实际执行结果不符:
- SQL语法错误+PreparedStatement参数使用不规范:更新语句拼接id参数时未闭合单引号,且id未使用
?占位符,实际生成的SQL存在语法错误,执行会直接失败。 - 事务未提交:如果JDBC连接默认关闭了自动提交,执行
executeUpdate()后未手动调用commit(),更新不会持久化到数据库。 - 资源未释放:Connection、PreparedStatement对象用完后未关闭,可能导致连接泄漏、事务状态异常。
- 异常处理逻辑错误:SQL执行抛出异常时仅打印堆栈,未中断后续逻辑,无论更新是否成功都会弹出成功提示,误导操作结果。
- 冗余对象创建:
onRowEdit方法中无需新建Config对象,直接从事件中获取编辑后的实体即可,该问题不影响功能但属于冗余代码。
修复方案
- 修正SQL语句,所有参数(包括id)统一使用
?占位符,禁止直接拼接参数到SQL字符串,避免SQL注入和语法错误。 - 确认JDBC连接开启自动提交,或执行更新后手动提交事务。
- 执行完成后按顺序关闭PreparedStatement、Connection资源,建议使用try-with-resources语法自动释放资源。
- 调整异常处理逻辑:更新失败时返回错误提示,不要固定弹出成功消息。
- 移除冗余的Config对象创建逻辑,直接使用事件返回的编辑后实体。
修正后的可运行代码如下:
public static void edit(Config f, int id) throws SQLException { // 所有参数用占位符,修正SQL语法 String updateSql = "update config set description=?, valeur=? where id=?"; // try-with-resources自动关闭连接和语句对象,无需手动释放 try ( DB_connection2 obj_DB_connection = new DB_connection2(); Connection connection = obj_DB_connection.get_connection(); PreparedStatement ps = connection.prepareStatement(updateSql) ) { // 按占位符顺序设置参数 ps.setString(1, f.getDescription()); ps.setInt(2, f.getValeur()); ps.setInt(3, id); // 执行更新 int affectedRows = ps.executeUpdate(); // 未开启自动提交时手动提交事务 if (!connection.getAutoCommit()) { connection.commit(); } // 影响行数为0说明更新失败,抛出异常触发错误提示 if (affectedRows == 0) { throw new SQLException("更新记录失败,未匹配到对应ID:" + id); } } } public void onRowEdit(RowEditEvent<Config> event) { Config editedConfig = event.getObject(); try { edit(editedConfig, editedConfig.getId()); FacesMessage msg = new FacesMessage("更新成功", "已修改记录ID:" + editedConfig.getId()); FacesContext.getCurrentInstance().addMessage(null, msg); } catch (Exception e) { FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "更新失败", e.getMessage()); FacesContext.getCurrentInstance().addMessage(null, msg); e.printStackTrace(); } }
额外校验项:确保PrimeFaces数据表的行编辑配置中,
p:ajax event="rowEdit"正确绑定了onRowEdit方法,且编辑列的字段与Config实体的属性名一一对应,避免前端传值为空导致更新异常。
内容的提问来源于stack exchange,提问作者Steph af
相关产品推荐
相关产品推荐

