[BETA] 使用 DTO
警告! 这个新特性目前还是 测试 阶段。谨慎使用!欢迎反馈!
介绍
默认情况下,JHipster 使用领域模型对象(domain objects,通常是 JPA 实体对象)直接给到 REST 端点。这样做有很多好处,主要好处是代码很简单,易于理解。
对于复杂的场景,你还是有可能会需要使用数据传输对象(Data Transfer Objects ,DTOs),被用来暴露给 REST 端点。这些对象在领域模型上增加了额外的一层,并对 REST 层做了优化和适配:主要的好处是他们可以集成多种领域模型。
JHipster 里的 DTO
当创建 JHipster 实体对象时,你可以增加一层服务层:DTO 选项也只会在你选择了服务层时才可用,因为它需要这一层来做映射 (如果你使用了 JPA,也因为这一层处理了事务,延迟加载才会正常工作)。
一旦你选择创建了服务层,你就可以选择创建实体对象的 DTO。如果你选择了该选项:
- 创建一个 DTO ,并映射到实体对象。
- 它会集合管理 many-to-one 关系,只使用 ID 和另一个在客户端显示的字段。以至于需要在 DTO 上添加一个 many-to-one 关系指向
User
对象,添加userId
字段和userLogin
字段。 - 它会在非管理端忽略 one-to-many 和 many-to-many 关系:这和实体对象的工作方式匹配 (他们会有个
@JsonIgnore
字段注解)。 - 对于 many-to-many 关系,在管理端:会从另一端实体使用 DTO,并把它们放在一个
Set
里。也就是,其他实体也是用了 DTO 的时候才会起作用。
使用 MapStruct 来映射 DTO 和实体
大部分 DTO 和实体对象看上去差不多,所以经常会有需要能在他们之间做自动映射。
这个章节介绍使用 MapStruct。这是一个组件处理器,作为 Java 编译器的插件,能自动创建所需的映射。
我们发现这是非常简洁有效的,并且不需要反射(反射在映射中的使用会有较大的性能影响)。
设置你的 IDE 来支持 MapStruct
MapStruct 是一种注释处理器,所以它需要在你的 IDE 编译项目的时候正确设置。
如果你使用的是 Maven,你需要启用 maven 的 IDE
profile。Gradle 用户不需要做任何设置。
启用这个 profile 的介绍参考: 配置你的 IDE.
高级 MapStruct 使用
MapStruct 的 mapper 配置为 Spring Bean,并支持依赖注入(dependency injection)。一个好的建议是你可以把 Repository
注入到 mapper 里,使你能用 ID 从 mapper 中抓取 JPA 实体。
这里是一个例子,抓取 User
实体:
@Mapper
public abstract class CarMapper {
@Inject
private UserRepository userRepository;
@Mapping(source = "user.id", target = "userId")
@Mapping(source = "user.login", target = "userLogin")
public abstract CarDTO carToCarDTO(Car car);
@Mapping(source = "userId", target = "user")
public abstract Car carDTOToCar(CarDTO carDTO);
public User userFromId(Long id) {
if (id == null) {
return null;
}
return userRepository.findOne(id);
}
}