我有两个类(实体和DTO)
public class Deliver {
private Long id;
private String uri;
private Instant moment;
private DeliverStatus status; // enum PENDING,ACCEPTED,REJECTED
private String feedback; // feedback about received task
private Integer correctCount; // nr of correct questions
private Enrollment enrollment;
private Lesson lesson;
// constructors, getters and setters..
public class DeliverRevisionDto {
private DeliverStatus status;
private String feedback;
private Integer correctCount;
// constructors, getters and setters..
目标很简单,更新Dto类传递的实体字段我在服务层有以下代码(Sping Boot 版本2.4.4):
@Service
public class DeliverService {
@Autowired
private DeliverRepository deliverRepository;
@Autowired
private ModelMapper modelMapper;
@Transactional
public void saveRevision(Long id, DeliverRevisionDto dto) {
Deliver deliver = deliverRepository.getOne(id);
System.out.println("BEFORE MAPPING: " + deliver.toString()); // # debug purpose
deliver = modelMapper.map(dto, Deliver.class);
// # debug purpose
TypeMap<DeliverRevisionDto, Deliver> tm = modelMapper.getTypeMap(DeliverRevisionDto.class, Deliver.class);
List<Mapping> list = tm.getMappings();
for (Mapping m : list)
{
System.out.println(m);
}
System.out.println("AFTER MAPPING: " + deliver.toString()); // # debug purpose
deliverRepository.save(deliver);
}
}
控制台输出为:
BEFORE MAPPING: Deliver [id=1, uri=``https://github/someone.com``, moment=2020-12-10T10:00:00Z, status=PENDING, feedback=null, correctCount=null, enrollment=com.devsuperior.dslearnbds.entities.Enrollment@7e0, lesson=com.devsuperior.dslearnbds.entities.Task@23]`
`PropertyMapping[DeliverRevisionDto.correctCount -> Deliver.correctCount]`
`PropertyMapping[DeliverRevisionDto.feedback -> Deliver.feedback]`
`PropertyMapping[DeliverRevisionDto.status -> Deliver.status]`
`AFTER MAPPING: Deliver [id=null, uri=null, moment=null, status=ACCEPTED, feedback=Muito bem cabra, tarefa aceita., correctCount=5, enrollment=null, lesson=null]
DTO中3个字段的Map正确完成,但实体的所有其他字段都设置为空。我知道可以根据http://modelmapper.org/user-manual/property-mapping/跳过字段
问题是我不想把代码和特定的字段名/getters/setters结合起来,这就是我使用ModelMapper的原因。我想知道是否有任何配置在MapModelMapper对象时说:“嘿,TARGET类比SOURCE类有更多的字段,我将无条件地保持它们不变(意味着我不需要说明字段是什么)。”
我试图在两个类之间Map字段,它们具有不同的字段集(有些是相同的),当我将具有较小字段集的类Map到具有较大字段集的类时,Map器将字段集设置为不匹配“null”,我希望这些字段保持不变(具有原始值),而无需我告诉它们是哪一个,毕竟,Map器知道哪些字段匹配。
1条答案
按热度按时间7lrncoxx1#
ModelMapper文档并不是该框架最好的部分,让我们看看代码中发生了什么。
在这里,您可以从存储库中获取要更新的实体:
并记录它的所有字段应该是。但是这一行:
对变量
deliver
进行重新赋值。此方法创建Deliver类的新示例,并将其赋值给变量deliver
,从而丢弃从repo获取的实体。此新示例将具有DTOnull中不存在或未设置的所有字段。
这是我的IDE提供的API文档,用于这两种不同的方法:
字符串org.modelmapper.ModelMapper.map(对象源,类destinationType)将源Map到destinationType的示例。Map根据相应的TypeMap执行。如果源.getClass()和destinationType不存在TypeMap,则创建一个。
对比
voidorg.modelmapper.ModelMapper.map(对象源,对象目标)
将源Map到目标。根据对应的TypeMap执行Map。如果源.getClass()和目标.getClass()不存在TypeMap,则创建一个。
第一个方法实际上是基于传递的类型(Class)创建一个新示例,这一点可能没有明确说明,但应该清楚的是,ModelMapper不能仅仅通过知道类型来更改某个任意变量。您需要将要更改的变量作为方法参数传递。