2012-01-04 13 views
18

Java date & tipos de datos de tiempo son como todos saben, no hay necesidad de centrarse en eso.¿Cómo operar con el tipo de datos de intervalo PostgreSQL utilizando jdbc/spring-jdbc sin usar PGInterval?

Sin embargo, cuando estoy usando JDBC o extensiones, como SimpleJdbcTemplate basada en primavera para recuperar y almacenar intervalo valores, qué tipo de Java debo usar, si no quiero usar org.postgresql.util .PGInterval clase?

Esta clase es interna del controlador PostgreSQL, por lo que usarla haría que el código sea específico de DB. Creo que debería ser posible operar en intervalos en forma de DB-agnóstico, porque es uno de los tipos de SQL estándar.

+1

Para evitar dependencias en las extensiones, por lo general terminan modificando mi consulta SQL para devolver una columna de cadena en lugar del tipo de encargo (si es posible). Entonces, en este caso, un "to_char (interval, formatString)", luego use el mapeador de filas en el lado del cliente para analizar y reconstituir el String recibido en un objeto apropiado. No es el más elegante, pero a menudo simple. – Glenn

Respuesta

14

Un intervalo no es uno de los tipos JDBC estándar, como se enumera en la clase java.sql.Types. Sé que si llama al resultSet.getObject("interval_column"), es un PGInterval cuando se convierte, por lo que parece que el controlador PG JDBC podría estar forzando su mano para tratarlo como tal, a menos que haga lo que dice Glenn y lo convierta en una cadena, o tal vez un número, en tu SQL.

En nuestra aplicación, utilizar JodaTime para todos de nuestra gestión de la fecha, y tenemos un tipo de hibernación escrita que convierte nuestra propiedad frijol hacia y desde un PGInterval, y utilizar getObject y setObject para comunicarse con JDBC. Dudo que el código lo ayude a tratar con lo que está buscando aquí, pero puedo compartirlo con usted si está interesado.

ACTUALIZADO: Aquí está la clase de tipo Hibernate que convierte entre Joda Time y PGInterval. Sé que esto no responde a la pregunta, pero el cartel original solicitó el código de muestra.

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

Si puede, puede publicar su (s) clase (s) de ayuda en algún lugar, por ejemplo en su respuesta aquí :) JodaTime podría ser una buena base de clase común para extender el soporte de JDBC en Spring –

Cuestiones relacionadas