2012-05-06 18 views
12

मैं एक हाइबरनेट मानदंड तैयार करता हूं जो जांच करेगा कि एक वर्ष के दौरान अनुबंध वैध है या नहीं। अनुबंध की मानक तिथि-क्षेत्र के रूप में प्रारंभ और समाप्ति तिथि है।हाइबरनेट मानदंड निकालने की तिथि

तो एसक्यूएल सर्वर के लिए इस्तेमाल किया जा रहा है, मैं इस एसक्यूएल की लाइनों में कुछ लगता होगा:

SELECT * FROM CONTRACT WHERE YEAR(startDate) <= ? AND YEAR(endDate) >= ? 

questionmark एक पूर्णांक के रूप में दिए गए वर्ष है।

तो इसे हाइबरनेट मानदंड में कैसे परिवर्तित करें?

int year = 2011; //Just a testyear for example purposes. 
DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", year)) 
    .add(Restrictions.ge("endDate", year)); 

आप देख सकते हैं, मैं थोड़ा जहां मैं एक साल में बदलने की तारीख की तो यह तुलना की जा सकती याद आ रही है। स्वाभाविक रूप से मेरा कोड इस तरह से नहीं चलता है।

वांछित परिणाम कैसे प्राप्त करें इस पर कोई सुझाव?

उत्तर

13

यह एपीआई सीधे समर्थन नहीं करता है जैसे आप चाहते हैं की तरह लगते हैं, लेकिन वैकल्पिक हल है कि आप पर विचार हो सकता है।

समाधान 1: दो विधियों में से

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", toEndOfYear(year)) 
    .add(Restrictions.ge("endDate", toStartOfYear(year))); 

public Date toStartOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND, 0); 
    return calendar.getTime(); 
} 

public Date toEndOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND,-1); 
    return calendar.getTime(); 
} 

उदाहरण आउटपुट:

System.out.println(toStartOfYear(2013)); 
System.out.println(toEndOfYear(2013)); 

Mon Dec 31 00:00:00 MYT 2012 
Sun Dec 30 23:59:59 MYT 2012 

समाधान 2:

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.sqlRestriction("YEAR(startDate) >= ? ", year,Hibernate.INTEGER)) 
    .add(Restrictions.sqlRestriction("YEAR(endDate) <= ? ", year,Hibernate.INTEGER)); 
+1

समाधान 1 एक अच्छा स्वच्छ विकल्प है, हालांकि 'toEndOfYear' विधि के लिए 1 जोड़ना चाहिए वर्ष के रूप में इसे 'cal.set' में पारित किया गया, अन्यथा आपको पिछले वर्ष का अंत मिलता है – Numeron

5

उपयोग Restrictions.sqlRestriction कि आपकी समस्या का समाधान होगा

3

आप जेपीए criteriaBuilder उपयोग करते हैं, आप कर सकते हैंका उपयोग करेंविधि। जैसे

contractRepository.findAll(new Specification<Contract>() { 
    @Override 
    public Predicate toPredicate(Root<Contract> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
    return cb.ge(cb.function("year", Integer.class, root.get(Contract_.endDate)), year); 
    } 
}); 

(मैं इस उदाहरण में स्प्रिंग डाटा Specifications का उपयोग करें। डेटाबेस क्वेरी करने के लिए contractRepository प्रकार JpaSpecificationExecutor की इस प्रकार है),

संबंधित मुद्दे