2012-01-04 21 views
18

Data Javy & Typy danych czasowych są takie, jak wszyscy wiedzą, nie trzeba się na tym skupiać.Jak obsługiwać typ danych interwału PostgreSQL przy użyciu polecenia jdbc/spring-jdbc bez użycia PGInterval?

Jednak kiedy używam JDBC lub wiosną opartych rozszerzeń, takich jak SimpleJdbcTemplate do pobierania i przechowywania interwału wartości, jakiego typu Java należy użyć, jeśli nie chcesz używać org.postgresql.util .PGInterval klasy?

Ta klasa jest wewnętrzna dla sterownika PostgreSQL, więc użycie jej spowodowałoby, że kod byłby specyficzny dla DB. Myślę, że powinno być możliwe operowanie w interwałach w trybie agnostycznym, ponieważ jest to jeden ze standardowych typów SQL.

+1

Aby uniknąć zależności o rozszerzeniach, zwykle kończy się modyfikując moje zapytanie do powrotu kolumnę String zamiast niestandardowego typu (jeśli to możliwe). Tak więc w tym przypadku "to_char (interval, formatString)", a następnie użyj programu odwzorowującego wiersze po stronie klienta, aby przeanalizować i ponownie utworzyć odebrany ciąg w odpowiednim obiekcie. Nie jest to najbardziej elegancki, ale często prosty. – Glenn

Odpowiedz

14

Przedział przedział nie jest jednym ze standardowych typów JDBC, wymienionych w klasie java.sql.Types. Wiem, że jeśli zadzwonisz pod numer resultSet.getObject("interval_column"), jest to PGInterval po odlaniu, więc wygląda na to, że sterownik PG JDBC może zmusić twoją rękę do radzenia sobie z tym jako takim, chyba że zrobisz to, co mówi Glenn i przekonwertujesz go na ciąg znaków, a może liczba w twoim SQL.

W naszej aplikacji, używamy JodaTime dla całej naszej gospodarki data i mamy to rodzaj hibernacji pisemnej który konwertuje naszą własność fasoli do iz PGInterval i używać getObject i setObject komunikować się z JDBC. Wątpię, by ten kod pomógł ci uporać się z tym, czego szukasz, ale mogę ci go udostępnić, jeśli jesteś zainteresowany.

AKTUALIZACJA: Oto klasa Hibernate Type, która konwertuje między czasem Joda i PGInterval. Wiem, że to nie odpowiada na pytanie, ale oryginalny plakat poprosił o przykładowy kod.

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

Jeśli możesz, możesz opublikować swoje klasy pomocnicze gdzieś, na przykład w odpowiedzi tutaj :) JodaTime może być dobrą wspólną fundacją klasową dla rozszerzenia wsparcia JDBC przez wiosnę –

Powiązane problemy