CriteriaQuery在选择时加入

时间:2018-07-18 10:56:32

标签: java hibernate spring-data-jpa hibernate-criteria criteria-api

我正在尝试调整由CriteriaQuery生成的SQL请求。

@Entity
@Table(name = "DOCUMENT")
@SequenceGenerator(name = "sequence.generator",sequenceName = "DOCUMENT_SEQ", allocationSize = 1)
public class Document {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence.generator")
    private Long id;
    //other data
}


@Entity
@Immutable
@Table(name = "DOCUMENT_VERSION")
public class DocumentVersionRegistry implements Serializable{

    @Id
    @Getter @Setter
    private Long id;    


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DOC_ID")
    @Getter @Setter
    private Document document;

    //other data    
}

这是我当前的建造者:

private Specification<Document> getDocumentWithVersions(filterparams){
    return new Specification<Document>() {
        public Predicate toPredicate(Root<Document> documentPath, CriteriaQuery<?> query, CriteriaBuilder builder){
            Subquery<Document> sq = query.subquery(Document.class);
            Root<DocumentVersionRegistry> version = sq.from(DocumentVersionRegistry.class);
            Predicate predicate = builpredicate(filterparams).toPredicate(version, query, builder);
            return documentPath.in(sq.select(version.get("document").as(Document.class)).where(predicate));
        }
    };
}

生成的请求如下:

select
    * 
from
    ( select
        document0_.*
    from
        DOCUMENT document0_ 
    where
        document0_.id in (
            select
                documentve2_.DOC_ID 
            from
                DOCUMENT_VERSION documentve2_ 
            //LOTS OF JOINS TO SUPPORT PREDICATES
            where
                //LOST OF PREDICATE BUSINESS LOGIC
            ) 
        order by
            document0_.id desc 
    ) 
where
    rownum <= ?;

要点是,我有很多数据,请求可以在6分钟内完成。

但是,如果我手动调整使用JOIN而不是subselect的请求,则只需11秒。

select
    * 
from
    ( select
        document0_.*
    from
        DOCUMENT document0_ 
    JOIN 
        (
            select
                documentve2_.DOC_ID 
            from
                DOCUMENT_VERSION documentve2_ 
            //LOTS OF JOINS TO SUPPORT PREDICATES
            where
                //LOST OF PREDICATE BUSINESS LOGIC
            )
    sq ON sq.DOC_ID= document0_.ID          
        order by
            document0_.id desc 
    ) 
where
    rownum <= ?;

如何更改子查询以加入CriteriaBuilder?

版本:DB是Oracle 11,spring-data-jpa版本1.7.4.RELEASE

0 个答案:

没有答案