我想在使用JOIN执行SQL查询后实现DTO映射:
查询:
public List<Businesses> findCompaniesBusinessesById(Integer id) {
String hql = "SELECT bus FROM " + Businesses.class.getName() + " bus "
+ " INNER JOIN " + Companies.class.getName() + " comp "
+ " ON comp.id = bus.company_id "
+ " WHERE bus.business_owner_id = :id "
+ " AND bus.business_owner_type = 'Merchant' "
+ " ORDER BY bus.id ASC";
TypedQuery<Businesses> query = entityManager.createQuery(hql, Businesses.class).setParameter("id", id);
List<Businesses> businesses = query.getResultList();
return businesses;
}
实体:
@Entity
@Table(name = "businesses")
public class Businesses {
@Id
@Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
@Column(length = 4)
private Integer business_owner_id;
@Column(length = 255)
private String business_owner_type;
@Column(length = 4)
private Integer company_id;
@Column
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime created_at;
@Column
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime updated_at;
.......
}
!注意!。在“企业”实体中,设计时没有属性name
。
DTO:
public class BusinessesDTO {
private Integer id;
private String name;
.......
}
!注意!在BusinessesDTO中,我们期望name
是设计好的,并且我们希望对其进行映射。
DTO映射:
@Mapper(config = BaseMapperConfig.class)
public interface BusinessesMapper {
BusinessesDTO toDTO(Businesses company);
.....
}
查询结果:
您会看到有一个列名。
我试图使用此代码来获取映射:
@Autowired
private BusinessesMapper businesses_mapper;
List<BusinessesDTO> list = null;
try {
list = StreamSupport.stream(merchantService.findCompaniesBusinessesById(id).spliterator(), false)
.map(businesses_mapper::toDTO)
.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
String joinedList = list.stream()
.map(BusinessesDTO::getName)
.collect(Collectors.joining(", "));
但是结果是我得到了NULL或NULL。由于某些原因,名称未正确映射,我找不到原因。你能告诉我我哪里错了吗?
答案 0 :(得分:1)
这对您设置的方式完全无效。
EntityManager
返回您的域对象。
这些都没有任何信息,使得select语句中的其他列位于何处。
因此,您的映射器没有什么可获取名称的。
您实际上需要从选择中返回名称。 一种有吸引力的选择是使用constructor expression to create the DTO directly。
答案 1 :(得分:0)
您是否尝试过使用元组?当您不想为每个查询添加大量的dto时非常方便
TypedQuery<Tuple> query = entityManager.createQuery(hql, Tuple.class);
List<Tuple> tuples = query.getResultList();
List<BusinessesDTO> list = new ArrayList<>();
tuples.forEach((record) ->
{
String name = (String) record.get("name");
BusinessesDTO dto = new BusinessesDTO(name);
list.add(dto);
});