Java域和DAO映射器



项目的结构是:Domain对象用于对其执行一些逻辑操作,DAO对象仅用于从数据库中保存和读取数据。在从数据库中读取DAO对象之后,有映射器,它们的工作是将DAO对象转换为Domain版本。

域对象示例:

public class User {
UserId userId;
String name;
ShoppingCart shoppingCart;
...
}
public class ShoppingCart {
ShoppingCartId shoppingCartId;
float price;
User user;
...
}

DAO对象示例:

public class UserDAO {
Long id;
String name;
ShoppingCartDAO shoppingCart;
...
}
public class ShoppingCartDAO {
Long id;
float price;
UserDAO user;
...
}

但是,当DAO对象与另一个对象有关系并且这种关系是双向的时,就会出现问题。

例如:@OneToOne关系中User对象有ShoppingCart对象,ShoppingCart有User对象。

映射器的思想是它们映射整个对象,因此User对象的映射器将把常规字段重写为UserDAO,并运行ShoppingCart的映射器,以便将其转换为ShoppingCartDAO并将其分配给UserDAO。但是,一旦它这样做了,ShoppingCart映射器将尝试将User映射到DAO,它最终会在一个映射器相互调用的循环中结束。

样本映射器:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UserDAOMapper {
public static UserDAO toDAO(User user) {
return UserDAO.builder()
.id(user.getUserId().getId())
.name(user.getName())
.shoppingCart(ShoppingCartDAOMapper.toDAO(user.getShoppingCar())
.build();
}
}

如何避免这样的循环,同时保持代码简单?到目前为止,我看到的唯一解决方案是使用Factory服务,它将接受对象内部对象的参数列表,并仅在传递的参数为空时才对其进行映射。

我注意到你的问题标记了domain-driven-design。领域驱动设计的关键原则之一是,每个聚合都有一个根,并且对该聚合的操作通过根发生。看看您提供的示例,它看起来像是封装被破坏了。

我建议重新考虑你的设计。有一些问题可以帮助你:

  • 用户是否可以在没有购物车的情况下存在(例如,当他刚刚登录时),或者在创建时分配给他一个空的购物车?
  • 购物车可以在没有用户的情况下存在吗(很可能不存在)->这可能是一个指针,在购物车上的所有操作实际上都必须通过它的聚合根用户。所以现在你可以问为什么User需要是ShoppingCart的属性,因为ShoppingCart永远不能直接访问,它总是必须通过User访问。

相关内容

  • 没有找到相关文章

最新更新