数据访问
为了方便、高效的将聚合对象加载和持久化,框架提供了常见的的数据访问接口 BasicEntityPoDao。
BasicEntityPo 定义了一个基本的实体持久化对象(Persist Object),需要所有实体对象将会转换为 BasicEntityPo。BasicEntityPo需要一个id来判断是否是同一个实体。
持久对象
持久对象(Persist Object)简称:Po。约定一个表对应一个持久对象,表字段和Po属性一样对应。
建议表字段下划线风格。
实体id全局唯一
我们都知道聚会根的id是全局范围唯一的,可对聚会根内关联的实体(如订单明细)的id只需在这个聚合根内唯一即可,如:1、2、3等简单序号做实体Id。如果采用这种方式就会导致这些实体id在全局范围不能保证唯一,需要加上聚合根id+实体id才能确定唯一。
订单表:id 订单明细表:id,order_id。
但是不太符合表设计,实体id没办法享受主键的便捷。所以这里建议实体Id全局唯一,这种约定还能享受动态sql执行。
提供常见的抽象实现 AbstractBasicEntityPoDaoImpl 通用实现,只依赖 datasource。
BasicEntityPoDaoHibPanacheImpl 是quarkus 环境下的推荐实现。
常见用法
public class OrderPersistence {
private final OrderPoDao orderPoDao;
private final OrderItemPoDao orderItemPoDao;;
@PersistHandler(type = PersistType.ADD)
public void doAdd(Order order) {
orderPoDao.insertPo(formatOrderPo(order));
// 批量一次性提交明细
orderItemPoDao.batchInsertPos(formatOrderItemPos(location));
}
@PersistHandler(type = PersistType.MODIFY)
protected void doModify(Location newAR, Location oldAR) {
// 动态更新数据。如果未发现变更的数据,将不会执行数据库操作
orderPoDao.updateEntityPo(formatOrderPo(newAR), formatOrderPo(oldAR));
// 动态更新批量明细数据。
// 此方式会依据实体id比较,新增的实体会走 insert,变更的实体会执行 update ,删除的实体会执行 delete。
BatchBasicEntityPoDiff.dynamicUpdate(formatOrderItemPos(newAR), formatOrderItemPos(oldAR), orderItemPoDao);
}
@PersistHandler(type = PersistType.REMOVE)
protected void doRemove(Location newAR, Location oldAR) {
orderPoDao.deletePosById(formatOrderPo(newAR));
orderItemPoDao.batchDeletePosById(formatOrderItemPos(oldAR));
}
// 订单转换为订单主表持久对象
private static OrderPo formatOrderPo(Order order) {
OrderPo po = new OrderPo();
po.setId(location.getId().getVal());
// 赋值其他属性到po 对象
return po;
}
// 明细实体转换为明细实体持久化对象
private static List<OrderItemPo> formatOrderItemPos(Order order) {
final List<OrderItemPo> itemPos = new ArrayList<>();
// 获取明细实体
final List<OrderItem> items = order.getItem();
if (CollectionUtil.isNotEmpty(items)) {
for (OrderItem item : items) {
OrderItemPo itemPo = new OrderItemPo();
itemPo.setId(item.getId().val());
// 添加明细和主表的关联
itemPo.setOrderId(order.getId().val());
// 赋值其他属性到po 对象
itemPos.add(itemPo);
}
}
return itemPos;
}
}
动态sql执行
BasicEntityPoDao.updateEntityPo 和 BatchBasicEntityPoDiff.dynamicUpdate 的动态SQL执行实现的依据就是依赖实体id全局唯一的特性。