2010-05-18 41 views
20
SELECT x FROM SomeClass 
WHERE x.dateAtt BETWEEN CURRENT_DATE AND (CURRENT_DATE + 1 MONTH) 

Trong tuyên bố JPQL trên, SomeClass có memebr dateAttr, mà là một java.util.Date và có một chú thích @Temporal(javax.persistence.TemporalType.DATE).Java: chức năng ngày JPQL để thêm một khoảng thời gian để một ngày khác

Tôi cần một cách để thực hiện bit (CURRENT_DATE + 1 MONTH) - rõ ràng là sai ở trạng thái hiện tại - nhưng không thể tìm thấy tài liệu có hàm ngày cho JPQL.

Bất kỳ ai có thể chỉ cho tôi theo hướng tài liệu tài liệu chức năng ngày JPQL (và cũng làm cách nào để thực hiện truy vấn cụ thể này)?

+0

Đây có phải là truy vấn theo một số phương pháp bạn muốn không? Hoặc điều này cần phải được kích hoạt trên thực thể đậu nó tự? IE: '@ PrePersist' hoặc' @ PreUpdate'? –

+0

@Shervin: Không, truy vấn không cần phải được thực hiện trong '@ PrePersist' hoặc' @ PreUpdate'. Truy vấn là một truy vấn được đặt tên trên một lớp thực thể JPA ('SomeClass'). – bguiz

+0

@Shervin: Ngoài ra, tôi biết rằng tôi có thể sử dụng Java để tính toán các thao tác 'Date' và sau đó chuyển nó vào truy vấn bằng tham số' :', tuy nhiên, tôi sẽ làm điều đó trong chính JPQL và tránh điều đó không cần thiết mã. – bguiz

Trả lời

17

Nếu bạn có một đối tượng ngày đó là + 1 tháng đã bạn có thể làm một cái gì đó như thế này:

public List findEmployees(Date endDate) { 
    return entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2") 
    .setParameter(1,new Date(), TemporalType.DATE) 
    .setParameter(2,endDate, TemporalType.DATE).getResultList(); 
} 

này tuy nhiên, đòi hỏi ngày có giá trị trước mặt.

CẬP NHẬT

Nếu bạn luôn muốn những tháng tiếp theo, bạn có thể sử dụng JodaTime trong đó có một api tuyệt vời và dễ dàng. Sau đó, bạn có thể sửa đổi truy vấn của bạn như thế này:

//Get next month 
DateTime dt = new DateTime(); 
entityManager.createQuery(
"SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2") 
.setParameter(1,new Date(), TemporalType.DATE) 
.setParameter(2,dt.plusMonths(1).toDate(), TemporalType.DATE).getResultList(); 
+3

Bạn đã thử phần JodaTime chưa? JPA có thể đối phó với 'DateTime' không? –

+0

@Pascal: Điểm tốt.Tôi quên phương thức toDate(). Điều này sẽ trả về một 'java.util.Date' –

+1

Cải thiện nhẹ:' .setParameter (1, dt.toDate(), TemporalType.DATE) '(một nhập ít hơn và nhất quán với dòng tiếp theo) –

4

Hoặc sử dụng commons-lang thay vì jodatime:

entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2" 
) 
.setParameter(1,new Date(), TemporalType.DATE) 
.setParameter(2,DateUtils.addMonths(new Date(), 1), TemporalType.DATE) 
.getResultList(); 

Nhưng tôi biết điều này không phải là những gì bạn đang yêu cầu và tôi khá chắc chắn nó không thể thực hiện chỉ trong JPQL, bạn sẽ phải chuyển một tham số hoặc sử dụng truy vấn có tên là

+0

'DateUtils'? Là một phần của JDK std hay nó là một thư viện như thời gian Joda? – bguiz

+0

nó nằm trong apache commons/lang, một thư viện mã nguồn mở được sử dụng trong nội bộ bởi nhiều khung công tác: http://commons.apache.org/lang/ –

+2

Tốt hơn để sử dụng Joda-Time vì thực hiện tham chiếu của JSR-310 (https : //jsr-310.dev.java.net/) –

15

JPQL tiêu chuẩn không hỗ trợ các hoạt động đó vào các ngày. Bạn sẽ phải sử dụng truy vấn gốc hoặc để thực hiện tính toán ở phía Java.

+1

Điều này vẫn đúng? – span

0

Cháu yêu quý,

Tôi đang sử dụng dữ liệu mùa xuân, đơn vị lưu CreatedDate như datetime, và trong kho như thế này:

@Query(value="SELECT t FROM MyEntity t WHERE t.createdDate Between ?1 and ?2") 
public List<MyEntity> findAllBetweenDates(Calendar from, Calendar to); 

vì vậy tôi không thể sử dụng:

setParameter(1,new Date(), TemporalType.DATE 

trong bean phụ trợ tôi sử dụng như sau:

//to set zero of hours,minutes,seconds and milliseconds 
    fromCalendar.set(java.util.Calendar.HOUR, 0); 
    fromCalendar.set(java.util.Calendar.MINUTE, 0); 
    fromCalendar.set(java.util.Calendar.SECOND, 0); 
    fromCalendar.set(java.util.Calendar.MILLISECOND, 0); 

    toCalendar.set(java.util.Calendar.HOUR, 0); 
    toCalendar.set(java.util.Calendar.MINUTE, 0); 
    toCalendar.set(java.util.Calendar.SECOND, 0); 
    toCalendar.set(java.util.Calendar.MILLISECOND, 0); 
    // add 1 days and decrease 1 millisecond 
    toCalendar.add(java.util.Calendar.DAY_OF_MONTH, 1); 
    toCalendar.add(java.util.Calendar.MILLISECOND, -1); 

    allEntities = myEntityRepository.findAllBetweenDates(fromCalendar, toCalendar); 
} 

và nó hoạt động tốt.

Các vấn đề liên quan