使用规范JPA选择少数列(DTO)

时间:2014-04-15 19:04:28

标签: spring spring-data spring-data-jpa

我使用的是spring-data-jpa版本1.5.1.RELEASE。

我的域名是:

public class MyDomain{
....
....
private String prop1;
private String prop2;
......
......
}

我的JPA规范是:

public final class MyDomainSpecs {

public static Specification<MyDomain> search(final String prop1,final String prop2) {

    return new Specification<MyDomain>() {
        public Predicate toPredicate(Root<MyDomain> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            // Some tests if prop1 exist .....
            Predicate predicate1 = cb.equal(root.get("prop1"), prop1);
            Predicate predicate2 = cb.equal(root.get("prop2"), prop2);
            return cb.and(predicate1, predicate2);
        }

    };
}

}

我的存储库:

public interface MyDomainRepository extends JpaRepository<MyDomain, Long>, JpaSpecificationExecutor<MyDomain> {
List<MyDomain> findAll(Specification<MyDomain> spec);
}

一切正常。 但我的需求(对于性能数据库调整)是不返回并从DB中选择MyDomain的所有字段。

我需要仅选择树属性(prop1,prop2,prop3),理想情况是在DTO对象中。

我不想将我的List<MyDomain>转换为List<MyDto>,因为我正在调整数据库请求。

所以,我没有找到任何方法来使用spring-data-Jpa和Specification。

任何想法?

谢谢

2 个答案:

答案 0 :(得分:0)

创建MyDomain的特殊版本(例如MyDomainSummaryLightMyDomain),其中只包含您要映射的字段。

基本示例

借鉴优秀的JPA WikiBook

假设JPA实体(即域类)如此:

@Entity
@Table(name="EMPLOYEE")
public class BasicEmployee {
  @Column(name="ID")
  private long id;       

  @Column(name="F_NAME")
  private String firstName;

  @Column(name="L_NAME")
  private String lastName;

  // Any un-mapped field will be automatically mapped as basic and column name defaulted.
  private BigDecimal salary;  
}

生成的SQL查询与

类似
SELECT ID, F_NAME, L_NAME, SALARY FROM EMPLOYEE

如果没有定义条件(where子句)。因此,为了概括基本情况,可以说查询列的数量等于实体中映射字段的数量。因此,实体中的字段越少,SQL查询中包含的列就越少。

您可以拥有一个Employee实体,例如20个字段和一个BasicEmployee,如上所述,只有4个字段。然后,为两者创建不同的存储库或不同的存储库方法。

效果考虑因素

但是,我严重怀疑你会看到明显的性能改进,除非你想省略的字段代表与其他实体的关系。在开始调整之前,请记录当前针对数据库发出的SQL,然后从该SQL中删除要省略的列,再次运行它并分析您获得的内容。

答案 1 :(得分:0)

现在这是不可能的。这是一张票,但不知道它是否会得到实施:https://jira.spring.io/browse/DATAJPA-51