【问题标题】:mapstruct map an id to an objectmapstruct 将 id 映射到对象
【发布时间】:2018-02-21 20:43:32
【问题描述】:

我有一个对象学校有一个对象人员,人员已经保存在数据库中,当我保存学校对象时,我给它一个人员 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= new Person();
   person.setId(id);
   return person;
  }
}

这里的问题是,当我显示人时,它会向我显示 id 及其值和其他属性为 null

【问题讨论】:

  • 你能分享你的PersonMapper和EntityMapper吗
  • thnx @Filip,我编辑了我的问题

标签: java mapstruct


【解决方案1】:

之所以你的Person 只显示设置了id 值是因为你的fromId 方法创建了一个空的Person 并且只设置了id。

我想你想从数据库中获取Person。

要实现这一点,您只需告诉 MapStruct 使用服务,或者您可以将其注入映射器并执行提取。

如果你有这样的服务:

public interface PersonService {

    Person findById(Long id);
}

还有你的映射器:

 @Mapper(componentModel = "spring", uses = { PersonService.class }) 
 public interface SchoolMapper extends EntityMapper<SchoolDTO, School>{ 

  @Mapping(source = "personId", target = "person") 
  School toEntity(SchoolDTO schoolDTO); 
 } 

【讨论】:

  • 它怎么知道调用哪个服务方法?
  • 我不能说“如何”,但它确实对我有用。我想componentModel = "spring" 启用弹簧魔法
  • 之所以起作用,是因为 MapStruct 从 Mapper#uses 中查找了已定义服务的所有方法。在这种特殊情况下,它将寻找一种将 Long 映射到 Person 的方法。这就是它使用该方法的原因
【解决方案2】:

我们可以通过引入 ReferenceMapper 来概括前面的答案,如下所示:

@Component
public class ReferenceMapper {

    @PersistenceContext
    private EntityManager entityManager;

    @ObjectFactory
    public <T> T map(@NonNull final Long id,  @TargetType Class<T> type) {
        return entityManager.getReference(type, id);
    }
}

那么,PersonMapper 将是:

@Mapper(componentModel = "spring", uses = {ReferenceMapper.class})
public interface PersonMapper {

    Person toEntity(Long id);
}

最后是 SchoolMapper:

@Mapper(componentModel = "spring",uses = {PersonMapper.class})
public interface SchoolMapper {

  @Mapping(source = "personId", target = "person") 
  School toEntity(SchoolDTO schoolDTO); 
}

生成的源是:

@Override
    public School toEntity(InDto dto) {
        if ( dto == null ) {
            return null;
        }

        School school = new School();

        school.setPerson( personMapper.toEntity( dto.getPersonId() ) );
        // other setters

        return school;
    }

【讨论】:

  • 谢谢,这对像我这样的新手很有帮助
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多