如何使用 jdbc/spring-jdbc 不使用 PGInterval 对 PostgreSQL 区间数据类型进行操作?

Posted

技术标签:

【中文标题】如何使用 jdbc/spring-jdbc 不使用 PGInterval 对 PostgreSQL 区间数据类型进行操作?【英文标题】:How to operate on PostgreSQL interval datatype using jdbc/spring-jdbc not using PGInterval? 【发布时间】:2012-02-02 09:58:18 【问题描述】:

Java 日期和时间数据类型众所周知,没有必要关注它。

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

这个类是 PostgreSQL 驱动程序内部的,因此使用它会使代码特定于 DB。我认为应该可以以与 DB 无关的方式对时间间隔进行操作,因为它是标准 SQL 类型之一。

【问题讨论】:

为了避免对扩展的依赖,我通常会修改我的 sql 查询以返回一个字符串列而不是自定义类型(如果可能的话)。所以在这种情况下,一个“to_char(interval, formatString)”,然后使用客户端的行映射器将接收到的字符串解析并重新构成一个适当的对象。不是最优雅的,但通常很简单。 【参考方案1】:

interval 不是java.sql.Types 类中列出的标准 JDBC 类型之一。我知道如果你调用resultSet.getObject("interval_column"),它在转换时是PGInterval,所以看起来PG JDBC驱动程序可能会强迫你的手这样处理它,除非你按照Glenn所说的将它转换为SQL 中的字符串,或者可能是一个数字。

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

更新:这里是在 Joda Time 和 PGInterval 之间转换的 Hibernate Type 类。我知道这不能回答问题,但原始发帖人要求提供示例代码。

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");
    

【讨论】:

如果可以,您可以在某处发布您的帮助程序类,例如在这里回答 :) JodaTime 可能是 Spring 扩展 JDBC 支持的一个很好的通用类基础 请给我示例 DAO 类以供JodaTimeDurationType 类使用

以上是关于如何使用 jdbc/spring-jdbc 不使用 PGInterval 对 PostgreSQL 区间数据类型进行操作?的主要内容,如果未能解决你的问题,请参考以下文章

我想反转堆栈,但我不知道如何使用递归来反转这个......如何在不使用递归的情况下反转堆栈

如何实际使用使用不和谐 oauth2 请求的数据

如何使用随机值生成数组,而不使用循环?

如何在 iOS 中使用 Crashlytics 而不使用 Fabric

- 如何解决:ParentDataWidget 使用不正确?

如何在不安装 Zend 框架的情况下使用 Zend 库