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

JDBC结合DAO模式通过MySQL item_id创建Item对象实现订单更新

订单添加商品功能实现指引

你当前开发库存管理系统订单更新模块的添加商品功能时,已在MySQL Workbench验证了插入语句的可行性,但JDBC实现中存在逻辑遗漏和SQL冗余问题,以下是具体修正方案。


已验证的测试SQL

你在数据库工具中跑通的语句如下:

INSERT INTO order_items (item_quantity, fk_item_id, fk_order_id) 
VALUES (1,  (SELECT item_id FROM items WHERE item_id= 1), (SELECT order_id FROM orders WHERE order_id=2));

注:该SQL中的嵌套子查询属于冗余写法,fk_item_id、fk_order_id本身就是存储对应主键的字段,你已经明确知道要插入的商品ID、订单ID,直接赋值即可,不需要额外执行子查询查表。


代码修正方案

1. Controller层逻辑调整

你当前只创建了带ID的空Item对象,没有调用DAO查询完整商品信息,调整后代码如下:

@Override
public Order update() {
    LOGGER.info("Please enter the id of the order you would like to update");
    Long orderId = utils.getLong();
    LOGGER.info("Please enter the ID of the item you wish to add");
    Long itemId = utils.getLong();
    LOGGER.info("Please enter the quantity of the item to add");
    int quantity = utils.getInt();

    ItemDAO itemDao = new ItemDAO();
    // 直接接收read方法返回的完整Item对象,对象内已包含id、名称、成本三个属性
    Item targetItem = itemDao.read(itemId);
    // 增加非空校验,避免用户输入不存在的商品ID
    if (targetItem == null) {
        LOGGER.error("Input item ID does not exist");
        return null;
    }
    System.out.println(targetItem);
    Order updateResult = orderDAO.addItem(new Order(targetItem, quantity, orderId));
    LOGGER.info("Order Updated\n");
    return updateResult;
}

2. OrderDAO层addItem方法优化

移除冗余的子查询和不必要的DAO内部查询调用,保持DAO层单一职责(仅负责当前关联表的数据写入):

public Order addItem(Order order) {
    // 简化SQL,外键字段直接用参数赋值
    String insertSql = "INSERT INTO order_items (item_quantity, fk_item_id, fk_order_id) VALUES (?, ?, ?)";
    try (Connection connection = DBUtils.getInstance().getConnection();
         PreparedStatement statement = connection.prepareStatement(insertSql)) {
        statement.setInt(1, order.getItemQuantity());
        // 从上层传入的完整Item对象中获取商品ID
        statement.setLong(2, order.getItem().getItemId());
        statement.setLong(3, order.getOrderId());
        statement.executeUpdate();
        System.out.println(order);
        // 插入完成后查询最新的订单信息返回
        return read(order.getOrderId());
    }  catch (Exception e) {
        LOGGER.debug(e);
        LOGGER.error(e.getMessage());
    }
    return null;
}

核心逻辑说明

你已经实现的ItemDAO.read(Long id)方法会根据传入ID查询商品表数据,再通过modelFromResultSet方法把数据库返回的字段封装成完整的Item对象,之前的代码问题在于调用了read方法但没有用变量接收返回值,所以拿不到填充了名称、成本属性的商品对象。
另外开发时需要注意DAO层的职责边界:ItemDAO只处理商品表的增删改查,OrderDAO只处理订单、订单商品关联表的操作,关联对象的查询和组装放在上层Controller/Service层完成,代码结构会更清晰易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:27:35