Zeitpunkt der Vergleich mit dem JPA criteria API
Bekam ich ein Angebot für die Datumsauswahl mit zwei Terminen: start
und end
, wo beide können leer sein. Ich möchte zum filtern einer Tabelle, in der die Entität hat genau einen Tag: date
.
So, hier sind einige Beispiele. Ich möchte zu entsprechen. Imaging-das Datum entspricht dem aktuellen Datum (17/07/2016).
- null - 17/07/2016 -> match
- 17/07/2016 - null -> match
- 17/07/2016 - 17/07/2016 -> match
- null - null -> Spiel alle
Das sind die Grenzfälle, in meine Meinung und der Grund, warum ich kämpfen, so viel.
Eigentlich mein code sieht wie folgt aus:
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Transaction> cq = cb.createQuery(Transaction.class);
Root<Transaction> root = cq.from(Transaction.class);
List<Predicate> predicates = new ArrayList<>();
Predicate startPredicate = cb.greaterThanOrEqualTo(root.get(Transaction_.date), start);
Predicate endPredicate = cb.greaterThanOrEqualTo(root.get(Transaction_.date), end);
predicates.add(startPredicate);
predicates.add(endPredicate);
cq.select(root).where(predicates.toArray(new Predicate[] {}));
TypedQuery<Transaction> query = getEm().createQuery(cq);
query.setFirstResult(firstRow);
query.setMaxResults(maxRow);
List<Transaction> resultList = query.getResultList();
Ich würde gerne eine Abfrage wie diese:
SELECT * FROM transaction
WHERE ((cast(date AS DATE) >= '2016-07-16' OR cast(date AS DATE) IS NULL))
AND ((cast(date AS DATE) <= '2016-07-17' OR cast(date AS DATE) IS NULL))
Bitte beachten Sie: Die statische Datum ist die Simulation einer start-und end-Datum. und date
ist die Tabelle, die Spalte.
Ich weiß, dass mein code falsch ist. Es entspricht nur reicht, ohne Berücksichtigung der null-Werte. Auch, wenn start und Ende ist am gleichen Tag, bekomme ich null Ergebnisse.
Hast du eine Idee? Wie Bearbeite ich mein code mit allen genannten Muster?
SELECT * FROM table_name WHERE (cast(start_date AS DATE) > '07/17/2016' OR cast(start_date AS DATE) IS NULL) AND (cast(end_date AS DATE) < '07/20/2016' OR cast(end_date AS DATE) IS NULL)
(oder mit der BETWEEN
- Klausel)? Es wäre dann einfacher und klarer zu fertigen die entsprechenden Kriterien Abfrage.Sorry mate, ich dachte nicht über diese option. In meinem Kopf war nur criteria-api, weil ich dachte, die Abfrage ist zu kompliziert (in meinem Kopf).Ihre Abfrage sieht soweit ganz gut aus. Ich fügte hinzu, ein update zu meiner Frage. Würden Sie mir einen Blick zu haben? 🙂
InformationsquelleAutor alexander | 2016-07-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe eine bestehende Datenbank-Tabelle mit dem Namen
discount
mit zwei Spalten vom TypTIMESTAMP
namensdiscount_start_date
unddiscount_end_date
in einer MySQL-Datenbank. Also, passen Sie bitte Ihre Abfrage nach dem Namen der Tabelle und der jeweiligen Spalten in dieser Tabelle.Den kompletten Kriterien-Abfrage basierend auf der SQL-Anweisung gegeben, die Frage kann wie folgt aufgebaut sein (ich hoffe, der code wäre selbsterklärend).
Produziert es die folgende SQL-Abfrage von Interesse sind (beide Felder sind inclusive, wie gesagt).
Getestet auf Hibernate 4.3.6 abschließende, sondern Durchschnittliche ORM-frameworks sollte die gleiche Abfrage ohne jegliche Modifikationen.
In dieser Methode
setParameter(parameter, startDate, TemporalType.DATE)
, der Letzte parameter, d.h.TemporalType.DATE
ist nur notwendig, wenn Sie eine Spalte vom TypDATETIME
oderTIMESTAMP
in Ihrer Datenbank, und Sie vergleichen möchten Termine ignorieren, die mal Teil eines solchen Spalten. Sie können einfach ausgeschlossen werden, dass parameter, wenn Ihre Spalten nicht über ein Zeit-Teil wieDATE
(MySQL).Können Sie, falls erforderlich, auch andere, date (time) - Umgang mit APIs wie
java.time
oderJodaTime
ersetzenDate
zusammen mitSimpleDateFormat
Meine Abfrage sieht wie folgt aus: ....
where (transactio0_.date>=? or transactio0_.date is null) and (transactio0_.date<=? or transactio0_.date is null)
Diese Abfrage auf eine Tabelle test gibt das richtige ResultSet :
SELECT * FROM test WHERE (start_date >= '2016/07/17' OR start_date IS NULL) AND (end_date <= '2016/07/17' OR end_date IS NULL)
. Es gibt Zeilen, die passend zu den angegebenen Terminen in die jeweiligen Spalten mit null-Zeilen, wenn überhaupt. Casting ist völlig unnötig, wenn die Art der beiden Spalten istDATE
(also nichtDATETIME
oderTIMESTAMP
). SoTemporalType.DATE
imsetParameter()
Methode zusammen mitExpression.as()
in diesen beiden Prädikate können ignoriert werden und haben keine sichtbaren Auswirkungen, die sich das Ergebnis in diesem FallSowohl die Spalten in der
test
Tabelle nämlichstart_date
undend_date
TypDATE
in MySQL. Also, die angegebenen Kriterien Abfrage dürfte so funktionieren wie Sie sollen (wieder casting ist nicht erforderlich, wenn die Art der Spalten ist wirklichDATE
. Einfach nur ausschließenTemporalType.DATE
zusammen mitExpression.as()
. Ich Sie Hinzugefügt, weil ich getestet habe, auf eine vorhandene Tabelle mit Spalten vom TypTIMESTAMP
).Es bekam. Danke!
InformationsquelleAutor Tiny