You need to enable JavaScript to run this app. 使用JDBC PreparedStatement向MySQL插入类别列表无数据生效问题
优惠活动
大模型
产品
解决方案
定价
更多

使用JDBC PreparedStatement向MySQL插入类别列表无数据生效问题

根因定位与修复方案

你遇到的“无异常抛出但数据未插入”的现象,是由几个叠加的逻辑错误导致的,逐点拆解如下:

  • 最核心的逻辑错误:方法内直接覆盖传入的参数集合
    拿到外部传入的category列表后,第一行代码就执行了category = new ArrayList<>();,直接把装有所有枚举值的非空列表替换成了空集合。后续for循环遍历的是这个新建的空列表,循环体完全不会执行——既不会做参数绑定,也不会触发SQL执行,整个流程无任何分支抛出异常,自然表现为程序正常结束但数据库无数据写入。
  • 参数绑定逻辑完全失效
    即便移除上面的集合覆盖代码,循环内的写法也存在错误:
    • statement.setString(1, category.toString()) 绑定的是整个List集合的字符串输出,不是当前遍历的单个Category实例的名称
    • 循环内写的category.add(categories)会在遍历非空集合时触发并发修改异常,直接导致流程中断
  • 枚举类的字段赋值缺陷
    你为Category枚举定义了两个重载构造器:一个接收int类型的分类编号,一个接收String类型的分类名称。但所有枚举常量初始化时,调用的都是接收int参数的构造器——给字符串名称字段赋值的构造器从未被触发,所有枚举实例的名称字段都是null,哪怕前面的执行逻辑跑通,写入数据库的NAME值也全是空值。
  • 执行效率优化
    当前循环内每遍历一个元素就单次执行一次SQL,频繁和数据库产生交互开销,数据量稍大时性能很差,可以配合JDBC批量执行能力优化。

修正后可正常运行的代码

修正后的addCategories方法

private ConnectionPool pool = ConnectionPool.getInstance();

@Override
public void addCategories(List<Category> category) throws SQLException {
    // 删除覆盖传入集合的错误代码,直接复用外部传入的列表
    Connection connection = pool.getConnection();
    boolean originalAutoCommit = connection.getAutoCommit();
    // 关闭自动提交,配合批量插入减少事务开销
    connection.setAutoCommit(false);

    // 使用try-with-resources自动释放PreparedStatement资源
    try (PreparedStatement statement = connection.prepareStatement(
            "insert into `couponsystem`.`categories` (NAME) VALUES (?)")) {

        for (Category singleCategory : category) {
            // 绑定当前单个分类的名称值,移除错误的集合toString逻辑
            statement.setString(1, singleCategory.name());
            // 将SQL加入批量执行队列,替代循环内单次executeUpdate
            statement.addBatch();
        }
        // 一次性提交所有批量插入操作
        statement.executeBatch();
        connection.commit();

    } catch (SQLException e) {
        // 出现异常时回滚未提交的事务,避免脏数据
        if (connection != null) {
            connection.rollback();
        }
        throw e;
    } finally {
        // 恢复连接原有的自动提交配置,避免放回连接池后影响其他业务使用
        connection.setAutoCommit(originalAutoCommit);
        pool.restoreConnection(connection);
    }
}

修正后的Category枚举类

public enum Category {
    // 枚举初始化时同时传入编号和名称,解决名称字段为null的问题
    FOOD(1, "FOOD"),
    ELECTRICITY(2, "ELECTRICITY"),
    RESTAURANT(3, "RESTAURANT"),
    VACATION(4, "VACATION"),
    HOTEL(5, "HOTEL");

    private final int catId;
    private final String catName;

    // 合并冗余的两个构造器,初始化时同时完成两个字段的赋值
    Category(int catId, String catName) {
        this.catId = catId;
        this.catName = catName;
    }

    public int getIDX() {
        return catId;
    }

    public String getName() {
        return catName;
    }
}

内容的提问来源于stack exchange,提问作者Daniel R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 11:45:08