Java 如何使用jdbc/spring jdbc而不是PGInterval对PostgreSQL interval数据类型进行操作?

Java 如何使用jdbc/spring jdbc而不是PGInterval对PostgreSQL interval数据类型进行操作?,java,spring,postgresql,jdbc,intervals,Java,Spring,Postgresql,Jdbc,Intervals,Java日期和时间数据类型是众所周知的,不需要关注它 但是,当我使用JDBC或基于Spring的扩展(例如SimpleJdbcTemplate)来检索和存储interval值时,如果我不想使用org.postgresql.util.PGInterval类,我应该使用什么Java类型 此类是PostgreSQL驱动程序的内部类,因此使用它会使代码特定于数据库。我认为应该可以以不依赖于DB的方式对间隔进行操作,因为它是标准SQL类型之一。间隔不是标准JDBC类型之一,如java.SQL.types类

Java日期和时间数据类型是众所周知的,不需要关注它

但是,当我使用JDBC或基于Spring的扩展(例如SimpleJdbcTemplate)来检索和存储interval值时,如果我不想使用org.postgresql.util.PGInterval类,我应该使用什么Java类型


此类是PostgreSQL驱动程序的内部类,因此使用它会使代码特定于数据库。我认为应该可以以不依赖于DB的方式对间隔进行操作,因为它是标准SQL类型之一。

间隔不是标准JDBC类型之一,如
java.SQL.types
类中所列。我知道如果你调用
resultSet.getObject(“interval\u column”)
,它在铸造时是一个
PGInterval
,所以它看起来像是pgjdbc驱动程序在强迫你手动处理它,除非你按照Glenn说的做,并在SQL中将它转换成字符串,或者数字

在我们的应用程序中,我们使用JodaTime进行所有的日期管理,我们编写了一个Hibernate类型,将bean属性转换为
PGInterval
,并使用
getObject
setObject
与JDBC通信。我怀疑这些代码是否能帮助您处理您在这里寻找的内容,但如果您感兴趣,我可以与您分享

更新:下面是Hibernate类型的类,它在Joda Time和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");
    }
}
package com.your.package.hibernate.types;
导入java.io.Serializable;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.sql.Types;
导入org.hibernate.hibernateeexception;
导入org.hibernate.usertype.usertype;
导入org.joda.time.DurationFieldType;
导入org.joda.time.Period;
导入org.joda.time.ReadableDuration;
导入org.joda.time.ReadablePeriod;
导入org.postgresql.util.PGInterval;
公共类JodaTimeDurationType
实现用户类型{
公共类returnedClass(){
返回ReadableDuration.class;
}
公共int[]sqlTypes(){
返回新的int[]{Types.OTHER};
}
公共对象nullSafeGet(ResultSet ResultSet,字符串[]名称,对象所有者)
抛出HibernateeException、SQLException{
试一试{
final PGInterval pgi=(PGInterval)resultSet.getObject(名称[0]);
最终整数年=pgi.getYears();
final int months=pgi.getMonths();
final int days=pgi.getDays();
final int hours=pgi.getHours();
final int mins=pgi.getMinutes();
最终双秒=pgi.getSeconds();
返回新期间(年、月、0、天、小时、分钟、(整数)秒、0)。到标准持续时间();
}
捕获(例外e){
返回null;
}
}
public void nullSafeSet(PreparedStatement语句、对象值、int索引)
抛出HibernateeException、SQLException{
如果(值==null){
语句.setNull(索引、类型.OTHER);
}
否则{
最终ReadablePeriod期间=((ReadableDuration)值).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());
最终pgi=新的pgi间隔(年、月、日、小时、分钟、秒);
语句.setObject(索引,pgi);
}
}
公共布尔等于(对象x、对象y)
抛出冬眠异常{
返回x==y;
}
公共整数哈希码(对象x)
抛出冬眠异常{
返回x.hashCode();
}
公共对象深度复制(对象值)
抛出冬眠异常{
返回值;
}
公共布尔可交换(){
返回false;
}
公共可序列化反汇编(对象值)
抛出冬眠异常{
抛出新的HibernateException(“未实现”);
}
公共对象汇编(可序列化缓存,对象所有者)
抛出冬眠异常{
抛出新的HibernateException(“未实现”);
}
公共对象替换(对象原始、对象目标、对象所有者)
抛出冬眠异常{
抛出新的HibernateException(“未实现”);
}
}

为了避免对扩展的依赖,我通常会修改sql查询以返回字符串列而不是自定义类型(如果可能的话)。因此,在本例中,使用“to_char(interval,formatString)”,然后使用客户端的行映射器解析接收到的字符串并将其重新构造为适当的对象。不是最优雅的,但通常很简单。如果可以的话,你可以在某个地方公布你的助手类,例如,你在这里回答:)JodaTime可能是Spring扩展JDBC支持的一个很好的通用类基础请给我一个示例DAO类,以了解
JodaTimeDurationType
类的用法