【问题标题】:Select fews columns (DTO) with specification JPA选择具有规范 JPA 的少数列 (DTO)
【发布时间】:2014-04-15 19:04:27
【问题描述】:

我正在使用 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 Object 中。

我不想将 My List&lt;MyDomain&gt; 转换为 List&lt;MyDto&gt; 因为我正在调整数据库请求。

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

有什么想法吗?

谢谢

【问题讨论】:

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


    【解决方案1】:

    目前这是不可能的。有一张票,但不知道它是否会被实施:https://jira.spring.io/browse/DATAJPA-51

    【讨论】:

      【解决方案2】:

      创建一个特殊版本的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 中删除要省略的列,再次运行并分析获得的结果。

      【讨论】:

      • 我的问题不是关于 Performance ,有一个 Performance Audit 表明在我们的上下文中我们需要删除 select * 。对于您的回复,您能否提供更多细节,这一点都不清楚。我需要一个基于 Spring-DATA-JPA 和规范 JPA 的解决方案。
      • select * 查询不好,这是真的。但是,我敢打赌,Spring Data JPA 和您的 JPA 提供者(Hibernate、EclipseLink 等)都不会创建这些,这让我非常惊讶。我将为不熟悉 JPA 的人提供一个示例。
      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 2012-09-26
      相关资源
      最近更新 更多