2009-06-11 43 views
15

Tôi có một bảng (trong Oracle 9 trở lên), nơi tôi cần tìm tất cả các mục nhập cho một ngày nhất định bằng Hibernate. Các mục có dấu thời gian (với kiểu dữ liệu 'ngày'). Một số mục có một thời gian, những người khác chỉ có một ngày. Điều này không thể thay đổi, vì đây là đầu ra của các ứng dụng khác mà tôi không thể thay đổi. Trong SQL, tôi sẽ viết điều gì đó dọc theo các dòng củaSử dụng HQL để truy vấn ngày tháng trong khi bỏ qua thời gian trên Oracle

SELECT * FROM table WHERE trim(table.date) = to_date('11.06.2009') 

để nhận tất cả các mục nhập cho ngày mà tôi đang tìm kiếm. Tôi đã tự hỏi làm thế nào tôi có thể nhận được Hibernate để làm điều này bằng cách sử dụng HQL. Tôi biết tôi có thể sử dụng SQL-truy vấn trong Hibernate, nhưng điều này có vẻ là ít sạch sẽ. Có cách nào để làm việc này không? Nếu có thể, cách này cũng nên hoạt động trên các cơ sở dữ liệu không có oracle, nơi dấu thời gian sẽ là kiểu dữ liệu.

Trả lời

14

Bạn có thể đặt hai ràng buộc vào HQL của mình, một quy tắc chỉ định lớn hơn hoặc bằng ngày bắt đầu của ngày bạn đang tìm kiếm và ngày xác định ít hơn ngày hôm sau.

ví dụ:

table.date >=11.06.2009 AND table.date < 11.07.2009 

HQL (cũng như SQL) cũng cho phép:

table.date between 11.06.2009 AND 11.07.2009 

Hãy nhớ between luôn là toàn diện, có nghĩa là nó là cả >=<= tương ứng.
tin chi tiết về between đây: http://www.coding-dude.com/wp/java/hibernate-java/hibernate-hql-between-expression/

2

Tôi nghĩ có hai cách để giải quyết này:

  1. Sử dụng một truy vấn criteria và thêm một SQLRestriction. Các hạn chế sẽ có dạng "trim ({alias} .date) =?". Một vấn đề ở đây có thể là việc chuyển đổi tham số đầu vào thành kiểu đúng trên Oracle (hoặc các DBMS khác). Bạn có thể cung cấp kiểu cần thiết (hibernate) làm tham số, nhưng nếu điều này phụ thuộc vào cơ sở dữ liệu, nó sẽ được mã hóa cứng.

  2. sử dụng formula trong bản đồ ngủ đông của bạn. Các bản đồ sẽ là:

 <class name="Person"> 
     <property name="birthDay" formula="trim(birthDay)"/> 
    </class>

Bây giờ bạn có thể sử dụng hệ thống đánh máy Hibernate để sử dụng một so sánh với một đối tượng java như thế này:

s.createCriteria(Person.class) 
.add(Restrictions.eq("birthDay", new java.sql.Date(System.currentTimeMillis()))) 
.list() 

Một vấn đề bạn sẽ phải với cả hai giải pháp là chức năng trim có thể không có sẵn trong cơ sở dữ liệu. Một giải pháp cho điều này (ví dụ: trong khi thử nghiệm trên HSQLDB) là đặt một import.sql vào bài kiểm tra classpath của bạn (điều này sẽ được chọn bởi Hibernate tự động) và tạo một thủ tục hoặc hàm ở đó. Bạn cũng có thể Alter table Person add column birthDay timestamp trong tệp đó để làm cho giản đồ được tạo ra hoạt động.

-1

bạn có thể sử dụng hàm trunc() để loại bỏ phần thời gian trong cột DATE.

ví dụ: select * from emp where trunc(emp_date) < trunc(current_date()-30)

lấy về tất cả các chi tiết nhân viên nào đã được sử dụng 1 tháng trước

+8

và nếu đó là tháng 2? – Setori

+0

Không có ý tưởng tốt để làm việc với các giá trị không đổi, cũng như Setori cho biết, có những tháng có ít hơn 30 ngày và những người khác có 31 ngày. – will824

2

Đối CustomHQL, bạn có thể thử trunc từ khóa

Đối với Ex:

SELECT T0.FirstName as FirstName ,T0.LastLoginDate as LastLoginDate FROM User T0 
WHERE (trunc(T0.LastLoginDate) >= :LastLoginDate) ORDER BY T0.LastLoginDate 

LƯU Ý: Trong đó :LastLoginDate là tham số.

Điều này có lợi cho tôi.

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