2012-01-04 135 views
18

Java日期&時間數據類型是每個人都知道的,沒有必要專注於此。如何使用不使用PGInterval的jdbc/spring-jdbc在PostgreSQL時間間隔數據類型上進行操作?

然而,當我使用JDBC或基於Spring的擴展,如對SimpleJdbcTemplate進行檢索和存儲間隔值,什麼Java類型我應該使用,如果我不希望使用org.postgresql.util .PGInterval類?

這個類是PostgreSQL驅動程序的內部,所以使用它會使代碼DB特定。我認爲應該可以按照數據庫不可知的方式對間隔進行操作,因爲它是標準SQL類型之一。

+1

爲了避免對擴展的依賴性,我通常最終會改變我的SQL查詢,以返回一個字符串列,而不是自定義類型(如果可能)。因此,在這種情況下,使用「to_char(interval,formatString)」,然後使用客戶端上的行映射器來解析並將接收的String重新組成一個適當的對象。不是最優雅的,但往往很簡單。 – Glenn 2012-01-19 18:26:44

回答

14

一種間隔不是標準的JDBC類型之一,如在java.sql.Types類中列出。我知道,如果你打電話給resultSet.getObject("interval_column"),它在鑄造時是PGInterval,所以它看起來像PG JDBC驅動程序可能會迫使你的手處理它,除非你按照Glenn的說法將其轉換爲字符串,或者可能一個數字,在你的SQL中。

在我們的應用中,我們使用JodaTime爲我們所有的數據管理,而我們寫了一個Hibernate類型,我們的bean屬性轉換和從PGInterval,並使用getObjectsetObject與JDBC通信。我懷疑代碼會幫助你處理你在這裏尋找的東西,但如果你有興趣,我可以與你分享。

更新:這裏是Hibernate Type類,它可以在Joda時間和PGInterval之間轉換。我知道這並沒有回答這個問題,但是原始的海報要求提供示例代碼。

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

如果可以的話,你可以在某處公開你的助手類,例如你在這裏回答:) JodaTime可能是一個很好的普通類基金,用於Spring支持JDBC的支持 – 2012-01-24 12:21:10

相關問題