2012-01-04 12 views
18

Data Java & I tipi di dati temporali sono come tutti sanno, non è necessario concentrarsi su questo.Come operare su un datatype con intervallo PostgreSQL usando jdbc/spring-jdbc senza usare PGInterval?

Tuttavia, quando sto usando JDBC o estensioni, come SimpleJdbcTemplate Primavera-based per recuperare e memorizzare intervallo valori, che tipo Java devo usare, se non voglio usare org.postgresql.util .PGInterval class?

Questa classe è interna al driver PostgreSQL, quindi utilizzarla renderebbe il codice specifico per DB. Penso che dovrebbe essere possibile operare su intervalli in modo agnostico DB, perché è uno dei tipi standard di SQL.

+1

Per evitare le dipendenze sulle estensioni, io di solito finiscono per modificare la mia query SQL per restituire una colonna di stringa piuttosto che il tipo personalizzato (se possibile). Quindi, in questo caso, un "to_char (interval, formatString)", quindi usa il mappatore di righe sul lato client per analizzare e ri-costituire la stringa ricevuta in un oggetto appropriato. Non il più elegante, ma spesso semplice. – Glenn

risposta

14

Un intervallo non è uno dei tipi JDBC standard, come elencato nella classe java.sql.Types. So che se chiami resultSet.getObject("interval_column"), è un PGInterval quando viene castato, quindi sembra che il PG JDBC potrebbe forzare la tua mano a gestirlo come tale, a meno che tu non faccia quello che dice Glenn e lo converta in una stringa, o forse un numero, nel tuo SQL.

Nella nostra applicazione, abbiamo utilizzare JodaTime per tutti i nostri gestione data, e abbiamo un tipo di Hibernate scritto che converte la nostra proprietà di fagioli da e verso un PGInterval, e utilizzare getObject e setObject per comunicare con JDBC. Dubito che il codice ti possa aiutare a gestire ciò che stai cercando qui, ma posso condividerlo con te se sei interessato.

AGGIORNATO: Ecco la classe di tipo Hibernate che converte tra Joda Time e PGInterval. So che questo non risponde alla domanda, ma il poster originale ha richiesto il codice di esempio.

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

Se puoi, puoi pubblicizzare le tue classi di supporto da qualche parte, ad esempio in risposta qui :) JodaTime potrebbe essere una buona base di classe comune per estendere il supporto JDBC entro la primavera –

Problemi correlati