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

发布于 2024-12-24 23:12:20 字数 285 浏览 3 评论 0原文

Java 日期&时间数据类型是众所周知的,没有必要关注这一点。

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

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

Java date & time datatypes are as everybody knows, there's no need to focus on that.

However, when I'm using JDBC or Spring-based extensions, such as SimpleJdbcTemplate to retrieve and store interval values, what Java type should I use, if I don't want to use org.postgresql.util.PGInterval class?

This class is internal of PostgreSQL driver so using it would make the code DB-specific. I think it should be possible to operate on intervals in DB-agnostic way, because it is one of standard SQL types.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瓜 2024-12-31 23:12:20

interval 不是标准 JDBC 类型之一,如 java.sql.Types 类中列出的那样。我知道,如果您调用 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");
    }
}

An interval isn't one of the standard JDBC Types, as listed in the java.sql.Types class. I know that if you call resultSet.getObject("interval_column"), it is a PGInterval when casted, so it looks like the PG JDBC driver might be forcing your hand to deal with it as such, unless you do what Glenn says and convert it to a string, or maybe a number, in your SQL.

In our application, we use JodaTime for all of our date management, and we have a Hibernate Type written that converts our bean property to and from a PGInterval, and use getObject and setObject to communicate with JDBC. I doubt that code would help you deal with what you are looking for here, but I can share it with you if you are interested.

UPDATED: Here is the Hibernate Type class that converts between Joda Time and PGInterval. I know this doesn't answer the question, but the original poster asked for the sample code.

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");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文