2014-02-06 8 views
5

Ich versuche zu verhindern, eine separate Abfrage für die Anzahl und eine für die eigentliche Abfrage erstellen müssen. Was ich gefunden habe, ist SesssionImpl :: createQuery dauert eine beträchtliche Zeit für eine komplexe Abfrage und durch Kombination von count und der Hauptabfrage kann ich dann einen Aufruf von createQuery eliminieren.Überwintert Unterstützung Anzahl (*) über()

In SQL kann ich so etwas wie

select count(*) over(), col_A, col_B 
from TABLE_XX 
where col_C > 1000 

Kann dies in Hibernate tun erreicht werden?

(Ich versuche, Native SQL zu vermeiden und HQL und frei stehende Kriterien bleiben. Mit nativen SQL besiegt den Zweck Hibernate zu verwenden. Mein System sowohl Oracle und Sybase unterstützt hat)

+1

Nun können Sie immer native SQL verwenden. Ich nehme an, du willst das vermeiden? –

+0

Ja, ich versuche native sql zu vermeiden und halte mich an HQL und abgelöste Kriterien. Die Verwendung von nativem SQL verhindert den Zweck der Verwendung von Hibernate. – user2596860

+0

Was ist Ihre zugrunde liegende Datenbank? –

Antwort

1

diese Weise können Sie für : -

return (Number) session.createCriteria("Book").setProjection(Projections.rowCount()).uniqueResult(); 
2

@Formula Anmerkung des Hibernate kann als Behelfslösung arbeiten. Geben Sie eine zusätzliche Spalte in Ihrer @Entity die Zählung darstellen, mit @Formula kommentierten die die COUNT OVER Abfrage enthält:

@Formula("count(*) over()") 
private Integer totalResults; 

Mit diesem Ansatz Hibernate Metzger die erzeugte SQL ein wenig, obwohl, so dass Sie auch ein registrieren müssen Interceptor, um die SQL aufzuräumen:

public class CountOverQueryInterceptor extends EmptyInterceptor { 

    private static final long serialVersionUID = -2980622815729060717L; 

    @Override 
    public String onPrepareStatement(String sql) { 
     return super.onPrepareStatement(cleanCountOver(sql)); 
    } 

    /** 
    * Cleans the "{@code count(*) over()}" query fragment from Hibernate's sql 
    * decoration "{@code count(*) <alias>.over()}". 
    */ 
    static String cleanCountOver(String sql) { 
     return sql.replaceAll("(?i) (count)\\(\\*\\) \\w+\\.(over) \\(\\)", " $1(*) $2() "); 
    } 

} 

Neben den expliziten Hibernate Abhängigkeiten (eher als reine JPA), gibt es einen weiteren Nachteil, so dass diese Spalte standardmäßig geladen werden, die einige unnötigen Aufwand zu Abfragen hinzufügen kann wo das Land t wird nicht benötigt. Es kann möglich sein, die Spalte optional und lazily loaded zu machen, aber dies erfordert Bytecode-Instrumentierung und fügt weitere Komplexitätsebenen hinzu.

@Formula("count(*) over()") 
@Basic(optional = true, fetch = FetchType.LAZY) 
private Integer totalResults; 
Verwandte Themen