看一个更新地址的场景 , 生单时设置收货地址 , 然后操作修改地址:
@Test void modifyAddress_update() { // 新订单部存在地址信息(没有 userAddress) Order order = null; { CreateOrderCommand command = createOrderCommand(30L); order = this.applicationService.createOrder(command); Assertions.assertNotNull(order.getId()); } // Lazy 加载 , 只加载 orderAddress // 修改后 , 只更新 OrderAddress String address = "修改地址"; this.applicationService.modifyAddress(order.getId(), address); Order orderInDB = this.repository.findById(order.getId()).get(); Assertions.assertEquals(address, orderInDB.getAddress().getDetail() ); }
运行测试用例 , 输出如下信息:
// createOrder 方法中 repository.save(order) 产生的 SQL: // 创建带有地址的订单 Hibernate: insert into tb_order_address (detail) values (?) Hibernate: insert into tb_order (user_address_id, price, status, user_id) values (?, ?, ?, ?) Hibernate: insert into tb_order_item (amount, price, product_id, product_name, status) values (?, ?, ?, ?, ?) Hibernate: insert into tb_order_item (amount, price, product_id, product_name, status) values (?, ?, ?, ?, ?) Hibernate: insert into tb_order_item (amount, price, product_id, product_name, status) values (?, ?, ?, ?, ?) Hibernate: insert into tb_order_item (amount, price, product_id, product_name, status) values (?, ?, ?, ?, ?) Hibernate: insert into tb_order_item (amount, price, product_id, product_name, status) values (?, ?, ?, ?, ?) Hibernate: update tb_order_item set order_id=? where id=? Hibernate: update tb_order_item set order_id=? where id=? Hibernate: update tb_order_item set order_id=? where id=? Hibernate: update tb_order_item set order_id=? where id=? Hibernate: update tb_order_item set order_id=? where id=? // modifyAddress 方法中 repository.findById(orderId) 产生的 SQL // 从 DB 中加载数据 , 构建内存的 Order 对象 Hibernate: select order0_.id as id1_0_0_, order0_.user_address_id as user_add5_0_0_, order0_.price as price2_0_0_, order0_.status as status3_0_0_, order0_.user_id as user_id4_0_0_ from tb_order order0_ where order0_.id=? // 在对 order.address 进行访问时 , 进行自动加载 Hibernate: select orderaddre0_.id as id1_1_0_, orderaddre0_.detail as detail2_1_0_ from tb_order_address orderaddre0_ where orderaddre0_.id=? // modifyAddress 方法中 this.repository.save(order) 产生的 SQL // OrderAddress 信息发生变化 , 将变更更新到数据库 Hibernate: update tb_order_address set detail=? where id=? // repository.findById(order.getId()) 产生的 SQL // 从 DB 中加载数据 , 构建内存的 Order 对象 , 进行结果检测 Hibernate: select order0_.id as id1_0_0_, order0_.user_address_id as user_add5_0_0_, order0_.price as price2_0_0_, order0_.status as status3_0_0_, order0_.user_id as user_id4_0_0_ from tb_order order0_ where order0_.id=?
从该用例可看出 , Jpa 具有:
- 懒加载能力 , 只有在访问到关联数据时才对数据进行加载
- 自动同步能力 , 新增对象通过 insert 将其插入数据库 , 修改对象通过 update 对数据库数据进行更新
修改地址是简单的一对一 , 那对于较复杂的一对多 , Jpa 是否也具有 懒加载 和 自动同步能力呢?
支付核心代码如下:
@Transactional(readOnly = false) public void paySuccess(PaySuccessCommand command){ Optional orderOptional = repository.findById(command.getOrderId()); if (orderOptional.isPresent()){ Order order = orderOptional.get(); order.paySuccess(command); this.repository.save(order); } } // Order 实体上的 paySuccess 方法 public void paySuccess(PaySuccessCommand paySuccessCommand){ this.setStatus(OrderStatus.PAID); this.items.forEach(OrderItem::paySuccess); } // OrderItem 上的 paySuccess 方法 public void paySuccess() { setStatus(OrderItemStatus.PAID); }
单元测试如下:
@Test void paySuccess() { Order order = null; { CreateOrderCommand command = createOrderCommand(50L); order = this.applicationService.createOrder(command); Assertions.assertNotNull(order.getId()); } PaySuccessCommand paySuccessCommand = new PaySuccessCommand(); paySuccessCommand.setOrderId(order.getId()); paySuccessCommand.setPrice(1000L); paySuccessCommand.setChanel("微信支付"); // Lazy 加载 , 只加载 orderItem // 修改后 , 更新 order 和 OrderItem this.applicationService.paySuccess(paySuccessCommand); Order orderInDB = this.repository.findById(order.getId()).get(); Assertions.assertEquals(OrderStatus.PAID, orderInDB.getStatus()); orderInDB.getItems().forEach(orderItem -> { Assertions.assertEquals(OrderItemStatus.PAID, orderItem.getStatus()); }); }
运行单元测试 , 控制台出现信息如下:
推荐阅读
- 联想x250u盘启动~~联想x250发热大吗?
- 淘宝创业故事和梦想,看看他是怎样成功创业的
- 手机相册几千张,教你3秒锁定想要的照片
- 市场监管总局|逆向思维:赚钱没你想象的那么容易,也绝不像你想象的那么难
- 个人如何创业,个人创业想法或项目
- 男生最理想的身高是多少 男性标准身高体重
- 黄鼠狼可以做宠物吗……想知道黄鼠狼可以吃吗?
- 周立波|从爆红上海滩到人人喊打,周立波所做得恶比你想象的多
- 郭晶晶|40岁钻石王老五!郭晶晶小叔子未婚还当官,网友:想嫁豪门抓紧
- 吴宗宪|43岁女星慧慈神隐7年,透露想跟吴宗宪道歉