我有一个Web项目,其中我使用CXF for WS,Spring for DI,Hibernate for persistence以及目前Orika for DO-DTO映射呈现WS api。这是我的两个实体:
@Entity
public class Course {
@Id
private Long courseId;
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "scheduleId")
private Schedule schedule;
...
}
@Entity
public class Schedule {
@Id
private Long scheduleId;
@Column
private String name;
@OneToMany(mappedBy="schedule")
private List<Course> courses;
...
}
我的问题是关于创建DTO对象时的正确方法。正如您所看到的,这些对象具有双向关系,因此当CXF将要将它们编组为WebService的XML时,创建1:1 DTO将导致循环引用。
这是我到目前为止所做的:
@Service("scheduleService")
public class ScheduleService extends AbstractService implements IScheduleService{
@Autowired
private IScheduleDAO scheduleDAO;
public List<ScheduleDTO> getSchedules() {
List<ScheduleDTO> schedulesDTO = new ArrayList<ScheduleDTO>();
List<Schedule> schedules = scheduleDAO.findAll();
for(Schedulep:schedules) {
schedulesDTO.add(this.map(p, ScheduleDTO.class));
}
return schedulesDTO;
}
@Override
@Transactional(readOnly=true)
public ScheduleDTO getSchedule(Long id) {
Schedule schedule = scheduleDAO.findById(id);
ScheduleDTO scheduleDTO = new ScheduleDTO();
this.map(schedule, scheduleDTO);
return scheduleDTO;
}
@Override
@Transactional(readOnly=true)
public ScheduleWithCoursesDTO getScheduleWithCourses(Long id) {
//loads schedule object and join fetchs all associated courses
Schedule schedule = scheduleDAO.findWithCourses(id);
ScheduleWithCoursesDTO sch = this.map(schedule, ScheduleWithCoursesDTO.class);
return sch;
}
}
正如您所看到的,我有一个ScheduleDTO
对象只有基本属性(无关系),然后是一个“特殊”ScheduleWithCoursesDTO
,其中包含CourseDTO
类列表包含基本属性。这样对我来说感觉很尴尬;我可以想到我需要使用Schedule
检索所有课程的用例,还可以使用我需要检索具有相关计划的课程的情况。是否是为您可能需要的每种关系组合创建这些“特殊DTO”对象的常用程序?我还有另一种方法吗?也许有办法告诉Orika或任何其他映射器忽略给定映射执行的某些属性(而不是全局配置)。
ScheduleDTO:
public class ScheduleDTO {
private Long scheduleId;
private String name;
}
ScheduleWithCoursesDTO
public class ScheduleWithCoursesDTO extends ScheduleDTO {
private List<CourseDTO> courses;
}
答案 0 :(得分:1)
是的,有一种方式,有些人喜欢这种&#34;语境&#34;映射。 就个人而言,我不喜欢这样,我更喜欢为每个用例都有一个合适的DTO,我想DTO是一个合同和/或文档,用于操作/服务中涉及的数据。
在Orika中映射代码仍然是一个Java代码,我们可以重新使用它,按照我们为&#34; business&#34;码。 创造新的DTO并不是我们可以拥有的大不了的,它不是问题。您可以随意使用NewScheduleDTO BasicInfoScheduleDTO FullDetailsScheduleDTO。
如果您确实有一些需要上下文映射/有条件的严重用例 您可以使用Orika Filter API或为每个上下文管理多个MapperFactory。