使用 org.mapstruct 框架的一对多关系映射
One to Many Relation mapping using org.mapstruct framework
如何使用 org.mapstruct 框架映射一对多关系?
DTO 类:
@Data
public class ScheduledJobDTO {
private String jobName;
private String jobGroup;
private String jobClass;
private String cronExpression;
private Boolean cronJob;
private Long repeatTime;
private Integer repeatCount;
private Set<ScheduledJobParamsDTO> paramtersDTOs;
}
@Data
@EqualsAndHashCode
public class ScheduledJobParamsDTO {
String name;
String value;
}
域 Classes -
@Data
@Entity
@Table(name = "scheduled_job")
public class ScheduledJob {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "job_name")
private String jobName;
@Column(name = "job_group")
private String jobGroup;
@Column(name = "job_class")
private String jobClass;
@Column(name = "cron_expression")
private String cronExpression;
@Column(name = "is_cron_job")
private Boolean cronJob;
@Column(name = "repeat_time")
private Long repeatTime;
@Column(name = "repeat_count")
private Integer repeatCount;
@Column(name = "trigger_start_date")
private LocalDate triggerStartDate;
@Column(name = "trigger_end_date")
private LocalDate triggerEndDate;
@Column(name = "created_at")
private LocalDate createdAt;
@Column(name = "modified_at")
private LocalDate modifiedAt;
@Column(name = "is_active")
private Boolean active;
@OneToMany(mappedBy = "scheduledJob")
private Set<ScheduledJobParams> parameters;
}
@Data
@Entity
@Table(name = "scheduled_job_params")
@EqualsAndHashCode
public class ScheduledJobParams {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "scheduled_job_id", nullable = false)
ScheduledJob scheduledJob;
String name;
String value;
}
映射器Class-
@Mapping(source = ".", target = ".")
@Mapping(source = "paramtersDTOs", target = "parameters")
ScheduledJob mapToDomain(ScheduledJobDTO scheduledJobDTO);
现在,上面的映射器正在映射 ScheduledJob 和 ScheduledJobParams,但是 ScheduledJobParams 引用了 ScheduledJob。
如何将引用 ScheduledJob 映射到 ScheduledJobParams?
您可以通过 @AfterMapping
和 @MappedTarget
来实现。这在参考文档中有描述:12.2. Mapping customization with before-mapping and after-mapping methods.
// Java 8+ otherwise you need to use an abstract class and a for-loop instead
@Mapper(componentModel = "spring")
public interface ScheduledJobMapper {
@Mapping(target = "parameters", source = "paramtersDTOs")
ScheduledJob mapToDomain(ScheduledJobDTO dto);
@AfterMapping
default void after(@MappingTarget ScheduledJob domain, ScheduledJobDTO dto) {
domain.getParameters().forEach(scheduledJobParams -> {
scheduledJobParams.setScheduledJob(domain);
});
}
}
但是,当您从 DTO 映射回 entity 时,我相信您不需要填充双向关系(这就是我对 “域” 的理解)。请注意,如果处理不当,打印或序列化此类对象即 JSON 或 XML 会抛出 java.lang.WhosebugError
。
如何使用 org.mapstruct 框架映射一对多关系?
DTO 类:
@Data
public class ScheduledJobDTO {
private String jobName;
private String jobGroup;
private String jobClass;
private String cronExpression;
private Boolean cronJob;
private Long repeatTime;
private Integer repeatCount;
private Set<ScheduledJobParamsDTO> paramtersDTOs;
}
@Data
@EqualsAndHashCode
public class ScheduledJobParamsDTO {
String name;
String value;
}
域 Classes -
@Data
@Entity
@Table(name = "scheduled_job")
public class ScheduledJob {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "job_name")
private String jobName;
@Column(name = "job_group")
private String jobGroup;
@Column(name = "job_class")
private String jobClass;
@Column(name = "cron_expression")
private String cronExpression;
@Column(name = "is_cron_job")
private Boolean cronJob;
@Column(name = "repeat_time")
private Long repeatTime;
@Column(name = "repeat_count")
private Integer repeatCount;
@Column(name = "trigger_start_date")
private LocalDate triggerStartDate;
@Column(name = "trigger_end_date")
private LocalDate triggerEndDate;
@Column(name = "created_at")
private LocalDate createdAt;
@Column(name = "modified_at")
private LocalDate modifiedAt;
@Column(name = "is_active")
private Boolean active;
@OneToMany(mappedBy = "scheduledJob")
private Set<ScheduledJobParams> parameters;
}
@Data
@Entity
@Table(name = "scheduled_job_params")
@EqualsAndHashCode
public class ScheduledJobParams {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "scheduled_job_id", nullable = false)
ScheduledJob scheduledJob;
String name;
String value;
}
映射器Class-
@Mapping(source = ".", target = ".")
@Mapping(source = "paramtersDTOs", target = "parameters")
ScheduledJob mapToDomain(ScheduledJobDTO scheduledJobDTO);
现在,上面的映射器正在映射 ScheduledJob 和 ScheduledJobParams,但是 ScheduledJobParams 引用了 ScheduledJob。
如何将引用 ScheduledJob 映射到 ScheduledJobParams?
您可以通过 @AfterMapping
和 @MappedTarget
来实现。这在参考文档中有描述:12.2. Mapping customization with before-mapping and after-mapping methods.
// Java 8+ otherwise you need to use an abstract class and a for-loop instead
@Mapper(componentModel = "spring")
public interface ScheduledJobMapper {
@Mapping(target = "parameters", source = "paramtersDTOs")
ScheduledJob mapToDomain(ScheduledJobDTO dto);
@AfterMapping
default void after(@MappingTarget ScheduledJob domain, ScheduledJobDTO dto) {
domain.getParameters().forEach(scheduledJobParams -> {
scheduledJobParams.setScheduledJob(domain);
});
}
}
但是,当您从 DTO 映射回 entity 时,我相信您不需要填充双向关系(这就是我对 “域” 的理解)。请注意,如果处理不当,打印或序列化此类对象即 JSON 或 XML 会抛出 java.lang.WhosebugError
。