首页 > 解决方案 > 使用构造函数表达式直接创建 DTO

问题描述

我想在使用 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 = "companies")
public class Companies implements Serializable {

    @Id
    @Column(name = "id", unique = true, updatable = false, nullable = false)
    private int id;

    @Column(length = 255)
    private String name;

    @Column
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime created_at;

    @Column
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime updated_at;
    ...

    public Companies(String name) {
       super();
       this.name = name;
    }
}

实体企业:

@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(", "));

我尝试实现构造函数表达式来直接创建 DTO,如下所示:

public List<Businesses> findCompaniesBusinessesById(Integer id) {
        String hql = "SELECT org.datalis.plugin.entity.Companies(comp.name) 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);

你知道使用构造函数的正确方法是什么吗?

java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
\-[METHOD_CALL] MethodNode: '('
  +-[METHOD_NAME] IdentNode: 'org.datalis.plugin.entity.Companies' {originalText=org.datalis.plugin.entity.Companies}
  \-[EXPR_LIST] SqlNode: 'exprList'
    \-[DOT] DotNode: 'companies1_.name' {propertyName=name,dereferenceType=PRIMITIVE,getPropertyPath=name,path=comp.name,tableAlias=companies1_,className=org.
    plugin.entity.Companies,classAlias=comp}
      +-[ALIAS_REF] IdentNode: 'companies1_.id' {alias=comp, className=org.datalis.plugin.entity.Companies, tableAlias=companies1_}
          \-[IDENT] IdentNode: 'name' {originalText=name}
  [SELECT org.datalis.plugin.entity.Companies(comp.name) FROM org.datalis.plugin.entity.Business

标签: javasqlspring-data-jpahql

解决方案


推荐阅读