2012-01-04 20 views
18

जावा तिथि & समय डेटाटाइप सभी जानते हैं, उस पर ध्यान देने की कोई आवश्यकता नहीं है।पीजीइंटरवाल का उपयोग न करने वाले jdbc/spring-jdbc का उपयोग करके PostgreSQL अंतराल डेटाटाइप पर कैसे संचालित करें?

हालांकि

, जब मैं पुनः प्राप्त और स्टोर करने के लिए अंतराल मूल्यों, क्या जावा प्रकार उपयोग करना चाहिए, अगर मैं org.postgresql.util उपयोग करने के लिए नहीं करना चाहती JDBC या स्प्रिंग आधारित इस तरह के SimpleJdbcTemplate के रूप में एक्सटेंशन, उपयोग कर रहा हूँ .PG अंतराल वर्ग?

यह कक्षा PostgreSQL ड्राइवर का आंतरिक है इसलिए इसका उपयोग कोड डीबी-विशिष्ट बना देगा। मुझे लगता है कि डीबी-अज्ञेय तरीके से अंतराल पर काम करना संभव होना चाहिए, क्योंकि यह मानक एसक्यूएल प्रकारों में से एक है।

+1

एक्सटेंशन पर निर्भरता से बचने के लिए, मैं आमतौर पर मेरी एसक्यूएल क्वेरी को संशोधित करने के लिए कस्टम प्रकार (यदि संभव हो तो) एक स्ट्रिंग स्तंभ के बजाय वापस जाने के लिए खत्म। तो इस मामले में, एक "to_char (अंतराल, प्रारूपस्ट्रिंग)", फिर क्लाइंट पक्ष पर पंक्ति मैपर का उपयोग करें और प्राप्त ऑब्जेक्ट को उचित ऑब्जेक्ट में पुन: व्यवस्थित करें। सबसे सुरुचिपूर्ण नहीं, लेकिन अक्सर सरल। – Glenn

उत्तर

14

अंतराल मानक जेडीबीसी प्रकारों में से एक नहीं है, जैसा कि java.sql.Types वर्ग में सूचीबद्ध है। मुझे पता है कि अगर आप resultSet.getObject("interval_column") पर कॉल करते हैं, तो यह PGInterval होता है जब इसे कास्ट किया जाता है, तो ऐसा लगता है कि पीजी जेडीबीसी चालक आपके हाथ को इस तरह से निपटने के लिए मजबूर कर सकता है, जब तक कि आप ग्लेन कहते हैं और इसे स्ट्रिंग में परिवर्तित न करें, या शायद एक संख्या, आपके एसक्यूएल में।

हमारे आवेदन में, हम अपने तारीख प्रबंधन के सभी के लिए JodaTime उपयोग करते हैं, और हम एक हाइबरनेट प्रकार लिखा है कि करने के लिए और एक PGInterval से हमारे सेम संपत्ति धर्मान्तरित है, और getObject और setObject का उपयोग JDBC के साथ संवाद करने। मुझे संदेह है कि कोड आपको जो कुछ भी ढूंढ रहा है उससे निपटने में मदद करेगा, लेकिन यदि आप रुचि रखते हैं तो मैं इसे आपके साथ साझा कर सकता हूं।

अद्यतन: यहां हाइबरनेट प्रकार श्रेणी है जो जोडा समय और पीजी इंटरवलवाल के बीच परिवर्तित होती है। मुझे पता है कि यह सवाल का जवाब नहीं देता है, लेकिन मूल पोस्टर ने नमूना कोड के लिए कहा है।

package com.your.package.hibernate.types; 

import java.io.Serializable; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 

import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 
import org.joda.time.DurationFieldType; 
import org.joda.time.Period; 
import org.joda.time.ReadableDuration; 
import org.joda.time.ReadablePeriod; 
import org.postgresql.util.PGInterval; 

public class JodaTimeDurationType 
    implements UserType { 

    public Class<?> returnedClass() { 
     return ReadableDuration.class; 
    } 


    public int[] sqlTypes() { 
     return new int[] {Types.OTHER}; 
    } 


    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) 
     throws HibernateException, SQLException { 

     try { 
      final PGInterval pgi = (PGInterval)resultSet.getObject(names[0]); 

      final int years = pgi.getYears(); 
      final int months = pgi.getMonths(); 
      final int days = pgi.getDays(); 
      final int hours = pgi.getHours(); 
      final int mins = pgi.getMinutes(); 
      final double secs = pgi.getSeconds(); 

      return new Period(years, months, 0, days, hours, mins, (int)secs, 0).toStandardDuration(); 

     } 
     catch (Exception e) { 
      return null; 
     } 
    } 


    public void nullSafeSet(PreparedStatement statement, Object value, int index) 
     throws HibernateException, SQLException { 

     if (value == null) { 
      statement.setNull(index, Types.OTHER); 
     } 
     else { 
      final ReadablePeriod period = ((ReadableDuration)value).toPeriod(); 

      final int years = period.get(DurationFieldType.years()); 
      final int months = period.get(DurationFieldType.months()); 
      final int days = period.get(DurationFieldType.days()); 
      final int hours = period.get(DurationFieldType.hours()); 
      final int mins = period.get(DurationFieldType.minutes()); 
      final int secs = period.get(DurationFieldType.seconds()); 

      final PGInterval pgi = new PGInterval(years, months, days, hours, mins, secs); 
      statement.setObject(index, pgi); 
     } 
    } 


    public boolean equals(Object x, Object y) 
     throws HibernateException { 

     return x == y; 
    } 


    public int hashCode(Object x) 
     throws HibernateException { 
     return x.hashCode(); 
    } 


    public Object deepCopy(Object value) 
     throws HibernateException { 
     return value; 
    } 


    public boolean isMutable() { 
     return false; 
    } 


    public Serializable disassemble(Object value) 
     throws HibernateException { 
     throw new HibernateException("not implemented"); 
    } 


    public Object assemble(Serializable cached, Object owner) 
     throws HibernateException { 
     throw new HibernateException("not implemented"); 
    } 


    public Object replace(Object original, Object target, Object owner) 
     throws HibernateException { 
     throw new HibernateException("not implemented"); 
    } 
} 
+0

यदि आप कर सकते हैं, तो आप कहीं भी अपने सहायक वर्ग (एसएस) को प्रचारित कर सकते हैं, उदाहरण के लिए आप यहां जवाब देते हैं :) जोडाटाइम वसंत द्वारा जेडीबीसी समर्थन को विस्तारित करने के लिए एक अच्छा आम वर्ग निधि हो सकता है –