java—hibernate(jpa)允许Map自定义列(即别名列)吗

zz2j4svz  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(326)

我有一个简单的实体,如图所示的属性很少。

查询如下

select *,concat(current_date - cre_dte::date)  as _days_ago
from test."general" 
where (current_date - cre_dte::date)=7 or (current_date - cre_dte::date)<11

我的实体是

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name = "general", schema = "test")
public class GeneralEntity implements Serializable {

    private static final long serialVersionUID = -2343243243242432341L;

    /**
     * id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    /**
     * loadNumber
     */
    @Column(name="load_number")
    private String loadNumber;

    /**
     * createdDate
     */
    @Column(name="cre_dte")
    private Date createdDate;

    @Formula(value = "_days_ago")
    private String _daysAgo;
}

我正在尝试Map要存储的实体 _days_ago 从我的本地查询到pojo。为此,我修改了pojo,添加了@formula。但似乎没有将此别名Map到我的属性。在我的jpa接口中,我的方法如下

@Query(nativeQuery = true,value = "select *, concat(current_date - cre_dte::date)  as _days_ago  from general where (current_date - cre_dte::date)=7 or (current_date - cre_dte::date)<11")
public List<GeneralEntity> getFewDaysAgo() throws Exception;
u59ebvdq

u59ebvdq1#

你可以用 @Formula 为此,例如:

public class GeneralEntity implements Serializable {
    ...
    @Formula("current_date - cre_dte::date")
    Integer daysAgo;
}

但我一般不建议这样做,因为每次获取generalentity实体时都会执行这样的操作。
通常,对于这个用例,最好使用定制的dto投影来处理这个问题。您可以使用以下内容:

class GeneralEntityDto {
    Long id;
    String loadNumber;
    Date createdDate;
    String daysAgo;
    // constructor + getters
}

还有这样一个问题:

@Query("select new com.mycompany.package.GeneralEntityDto(g.id, g.loadNumber, g.createdDate, concat(current_date - cast(g.createdDate as date)) from GeneralEntity where (current_date - cast(g.createdDate as date))=7 or (current_date - cast(g.createdDate as date))<11")
public List<GeneralEntityDto> getFewDaysAgo();

如果您有更复杂的需求,比如需要Map集合,那么您应该尝试一下blaze持久性实体视图。
我创建了这个库,以便在jpa模型和自定义接口或抽象类定义的模型之间进行简单的Map,比如spring数据在steroids上的投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过jpql表达式将属性(getter)Map到实体模型。
对于blaze持久性实体视图,用例的dto模型可以如下所示:

@EntityView(GeneralEntity.class)
public interface GeneralEntityDto {
    @IdMapping
    Long getId();
    String getLoadNumber();
    Date getCreatedDate();
    @Mapping("DAY_DIFF(CAST_DATE(createdDate), current_date)")
    String getDaysAgo();
}

查询是将实体视图应用于查询的问题,最简单的就是按id进行查询。 GeneralEntityDto a = entityViewManager.find(entityManager, GeneralEntityDto.class, id); spring数据集成允许您像spring数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_us/index.html#spring-数据特征

public default List<GeneralEntityDto> getFewDaysAgo() {
    return findAll((root, query, criteriaBuilder) -> {
        Expression e = criteriaBuilder.function("DAY_DIFF", root.get(createdDate).as(java.sql.Date.class), criteriaBuilder.currentDate());
        return criteriaBuilder.or(
            criteriaBuilder.equal(e, criteriaBuilder.literal(7)), 
            criteriaBuilder.lessThan(e, criteriaBuilder.literal(1))
        );
    });
}

public List<GeneralEntityDto> findAll(Specification s);

相关问题