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
相关产品推荐
相关产品推荐

