我有两个这样的域类。
@Getter
@Setter
public class User {
private String name;
}
Run Code Online (Sandbox Code Playgroud)
@Getter
@Setter
public class Student extends User {
private int grade;
}
Run Code Online (Sandbox Code Playgroud)
我还有两个这样的 Dto 课程。
@Getter
@SuperBuilder
public class UserDto {
private final String name;
}
Run Code Online (Sandbox Code Playgroud)
@Getter
@SuperBuilder
public class StudentDto extends UserDto {
private final int grade;
}
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个扩展 GenericMapper 的映射器类 StudentMapper。
public interface GenericMapper<D, E> {
D toDto(E e);
E toEntity(D d);
}
Run Code Online (Sandbox Code Playgroud)
@Mapper(componentModel = "spring")
public interface StudentMapper extends GenericMapper<StudentDto, Student> {
}
Run Code Online (Sandbox Code Playgroud)
但是我在编译Mapper时出错了。
“StudentDto 没有可访问的构造函数。” …
我希望 MapStruct 映射我的 Object 的每个属性,除了我想为其提供自定义映射的一个特定属性。
到目前为止,我自己实现了整个映射器,但是每次我向实体添加新属性时,我都会忘记更新映射器。
@Mapper(componentModel = "cdi")
public interface MyMapper {
MyMapper INSTANCE = Mappers.getMapper(MyMapper.class);
default MyDto toDTO(MyEntity myEntity){
MyDto dto = new MyDto();
dto.field1 = myEntity.field1;
// [...]
dto.fieldN = myEntity.fieldN;
// Custom mapping here resulting in a Map<> map
dto.fieldRequiringCustomMapping = map;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将我的字段 fieldRequiringCustomMapping 的映射外包并告诉 MapStruct 像往常一样映射所有其他字段?
有多种方法可以忽略 mapstruct 中未映射的目标属性。
@Mapping(target = "propName", ignore = true)
Run Code Online (Sandbox Code Playgroud)
@Mapper(
unmappedTargetPolicy = ReportingPolicy.IGNORE
)
Run Code Online (Sandbox Code Playgroud)
有没有办法混合这些方法并忽略方法级别的所有属性而不明确列出所有属性?
这是一个用于映射的映射器接口:
@Mapper
public interface DoctorMapper {
DoctorMapper INSTANCE = Mappers.getMapper(DoctorMapper.class);
DoctorDto toDto(Doctor doctor);
}
Run Code Online (Sandbox Code Playgroud)
这是一个模型类:
public class Doctor {
private int id;
private String name;
// getter and setter and constructors
}
Run Code Online (Sandbox Code Playgroud)
这是一个模型类:
public class DoctorDto {
private int id;
private String name;
// getter and setter and constructors
}
Run Code Online (Sandbox Code Playgroud)
控制器类:
@RestController
public class SimpleController {
@RequestMapping("/")
String hello() {
Doctor d= new Doctor(1,"Hari");
DoctorDto doctorDto = DoctorMapper.INSTANCE.toDto(d);
System.out.println(doctorDto.toString());
return "Hello World, Spring Boot!";
}
}
Run Code Online (Sandbox Code Playgroud)
有什么建议将 doctor 实体映射到 doctordto …
我正在尝试使用具有 Date (java.util.Date) 字段的 Mapstruct 的映射器将对象转换为具有 LocalDateTime 字段的对象。问题在于它映射的时间错误,因为在具有 LocalDateTime 字段的对象中它总是显示少 2 小时。
@Mapping(source = "createdDate", target = "createdLocalDateTime")
ObjectA toEntity(ObjectB);
Run Code Online (Sandbox Code Playgroud)
我认为问题在于自动实现:
if ( createdDate!= null ) {
objectA.createdLocalDateTime( LocalDateTime.ofInstant( createdDate.toInstant(), ZoneId.of( "UTC" ) ) );
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?谢谢!
这是我第一次尝试使用 gradle,我遇到了一些我从未听说过的奇怪问题。谷歌并没有给我太多帮助,所以我谦虚地寻求一些帮助。在添加注释实体后,我的 dao Recipe 出现了一些问题,我开始使用 mapstruct。
我的 gradle 文件中有 2 个与 mapstruct 相关的依赖项
实现 'org.mapstruct:mapstruct:1.5.2.Final'
注释处理器'org.mapstruct:mapstruct-processor:1.5.2.Final'
这是我的代码错误,有趣的是代码运行良好,但我无法再次编译它。如果您需要一些代码,我会很乐意提供,正如您在屏幕上看到的那样,我生成了一些代码,但我不确定它何时以及为何停止工作。
Internal error in the mapping processor: java.lang.RuntimeException: javax.annotation.processing.FilerException: Attempt to recreate a file for type recipes.mapper.RecipeMapperImpl at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.createSourceFile(MapperRenderingProcessor.java:59) at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.writeToSourceFile(MapperRenderingProcessor.java:39) at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.process(MapperRenderingProcessor.java:29) at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.process(MapperRenderingProcessor.java:24) at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:350) at org.mapstruct.ap.MappingProcessor.processMapperTypeElement(MappingProcessor.java:330) at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:279) at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:174) at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62) at org.gradle.api.internal.tasks.compile.processing.IsolatingProcessor.process(IsolatingProcessor.java:50) at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62) at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$401(TimeTrackingProcessor.java:37) at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:99) at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:96) at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117) at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.process(TimeTrackingProcessor.java:96) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:985) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:901) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1227) at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1340) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1258) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:936) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104) at …Run Code Online (Sandbox Code Playgroud) 我在使用依赖注入的Spring应用程序中使用MapStruct从JPA实体映射到POJO DTO.
我已经在文档中指定的装饰器中添加了一些DTO处理方法.
它适用于映射单个实体.但是我也有这些实体的集合(集合)的映射,当在关系中找到这些实体的集合时,会自动调用该方法.
但是生成的集合映射方法不使用装饰方法来映射每个实体,只是在委托上使用"vanilla"生成的方法.以下是生成方法的代码:
@Override
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set) {
return delegate.missionSetToTreeDtoSet( set );
}
Run Code Online (Sandbox Code Playgroud)
委托方法本身不知道装饰器并调用单独的项目映射方法:
@Override
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set) {
if ( set == null ) {
return null;
}
Set<DimensionItemTreeDTO> set__ = new HashSet<DimensionItemTreeDTO>();
for ( Mission mission : set ) {
set__.add( missionToTreeDto( mission ) ); //here the decorator is not called !
}
return set__;
}
Run Code Online (Sandbox Code Playgroud)
...并且永远不会为集合中的项目调用装饰方法.
有没有一种方法可以让Mapstruct在集合映射中使用装饰器方法,而不是在我的装饰器中手动编写集合方法(它工作但是很冗长并且无法使MapStruct首先出现的目的是不必写这种代码)?
我有一些自动生成的枚举,我需要映射到MapStruct映射器中的布尔值.它们是这样的:
enum YN {
Y("Y"), N("N")
}
enum ZO {
_0("0"), _1("1")
}
Run Code Online (Sandbox Code Playgroud)
我试过使用@ValueMappings(),但它不起作用:
@ValueMappings({
@ValueMapping(source="Y", target=true),
@ValueMapping(source="N", target=false)
)
Boolean map(YN value);
Run Code Online (Sandbox Code Playgroud)
我该如何实现这种映射?
当我尝试mapper在2 classesin 之间创建一个时mapstruct,
我在warning编译代码时得到了:
src/main/java/mapstruct/DogMapper.java:15: warning: Unmapped target property: "otherField".
Cat convert(Dog dog);
^
1 warning
Run Code Online (Sandbox Code Playgroud)
这是我要映射的两个对象:
狗
@Getter
@Setter
public class Dog {
private String say;
}
Run Code Online (Sandbox Code Playgroud)
猫
@Getter
@Setter
public class Cat {
private String say;
private String otherField;
}
Run Code Online (Sandbox Code Playgroud)
这是我的Mapper
@Mapper
public interface DogMapper {
DogMapper mapper = Mappers.getMapper( DogMapper.class );
@Mapping(source = "say", target = "say")
Cat convert(Dog dog);
}
Run Code Online (Sandbox Code Playgroud)
我阅读了mapstruct docs,我知道我可以通过多种方式排除此特定字段:
@Mapping(ignore = true, target …Run Code Online (Sandbox Code Playgroud) 我有一个对象学校,其中有一个对象人,人已经保存在数据库中,当我保存学校对象时,我给它一个人ID
因此在班级学校中,我有一个类型为Person的属性person,在SchoolDTO中,我有一个类型为Long的属性personId
@Mapper(componentModel = "spring", uses = { PersonMapper.class })
public interface SchoolMapper extends EntityMapper<SchoolDTO, School>{
@Mapping(source = "personId", target = "person")
School toEntity(SchoolDTO schoolDTO);
}
School school = schoolMapper.toEntity(schoolDTO);
log.info(school.getPerson());
public interface EntityMapper <D, E> {
E toEntity(D dto);
D toDto(E entity);
List <E> toEntity(List<D> dtoList);
List <D> toDto(List<E> entityList);
}
@Mapper(componentModel = "spring", uses = {})
public interface PersonMapper extends EntityMapper<PersonDTO, Person> {
default Person fromId(Long id) {
if (id == null) {
return null;
}
Person person= …Run Code Online (Sandbox Code Playgroud)