2009-12-22 48 views
8

Theo PostgreSQL, tôi đang sử dụng PersistentDuration để ánh xạ giữa khoảng thời gian loại sql & thời gian nhưng nó không hoạt động.Cách ánh xạ kiểu Interval trong Hibernate?

Một người dùng khác tìm thấy cùng một vấn đề & đi kèm với lớp của mình:

public void nullSafeSet(PreparedStatement statement, Object value, int index) 
     throws HibernateException, SQLException { 
    if (value == null) { 
     statement.setNull(index, Types.OTHER); 
    } else { 
     Long interval = ((Long) value).longValue(); 
     Long hours = interval/3600; 
     Long minutes = (interval - (hours * 3600))/60; 
     Long secondes = interval - (hours * 3600) - minutes * 60; 
      statement.setString(index, "'"+ hours +":" 
        + intervalFormat.format(minutes) + ":" 
        + intervalFormat.format(secondes)+"'"); 

    } 
} 

Nhưng nó không làm việc với các định dạng thực bởi vì nó cho rằng mô hình khoảng cách chỉ là "hh: mm: ss" . Đó không phải là trường hợp: xem

Dưới đây một số ít ví dụ thực tế tôi cần phải phân tích từ cơ sở dữ liệu:

 
1 day 00:29:42 
00:29:42 
1 week 00:29:42 
1 week 2 days 00:29:42 
1 month 1 week 2 days 00:29:42 
1 year 00:29:42 
1 decade 00:29:42 

http://www.postgresql.org/docs/current/interactive/datatype-datetime.html

Có bạn một giải pháp sạch?

Trả lời

0

Theo liên kết, bạn sẽ có một ngày theo sau giờ: phút: giây. Vì vậy, thay đổi mã để một cái gì đó như sau giả định bạn không bao giờ cần phải có nhiều hơn sau đó 23 giờ 59 phút trong khoảng thời gian.

statement.setString(index, "'0 "+ hours +":" 
+ intervalFormat.format(minutes) + ":" 
+ intervalFormat.format(secondes)+"'"); 

Tôi không thể kiểm tra mã này vì tôi chưa cài đặt PostGreSql. Đối với một cuộc thảo luận khác về cùng một vấn đề này, hãy xem liên kết sau, mặc dù bạn sẽ phải sửa đổi mã được cung cấp để xử lý giây. Đó không phải là một vấn đề lớn.

https://forum.hibernate.org/viewtopic.php?p=2348558&sid=95488ce561e7efec8a2950f76ae4741c

+0

Không bắt buộc phải có một day.And có không chỉ là ngày keywork (năm, tháng, tuần, .. thấy liên kết ở trên) Dưới đây một số ví dụ thực tế từ cơ sở dữ liệu: -1 ngày 00: 29:42 -00: 29: 42 -1 tuần 00:29:42 1 tuần 2 ngày 00:29:42 1 tháng 1 tuần 2 ngày 00:29:42 -1 năm 00:29:42 1 thập kỷ 00:29:42 – adam

3

Đây là một giải pháp làm việc cho JPA, Hibernate (với chú thích).

Đây là sự khởi đầu của lớp thực thể (đối với bảng có cột Interval):

@Entity 
@Table(name="table_with_interval_col") 
@TypeDef(name="interval", typeClass = Interval.class) 
public class TableWithIntervalCol implements Serializable { 

Đây là cột khoảng:

@Column(name = "interval_col", nullable = false) 
@Type(type = "interval")  
private Integer intervalCol; 

Và đây là lớp Interval:

package foo.bar.hibernate.type; 

import java.io.Serializable; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 
import java.util.Date; 

import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 
import org.postgresql.util.PGInterval; 


/** 
* Postgres Interval type 
* 
* @author bpgergo 
* 
*/ 
public class Interval implements UserType { 
    private static final int[] SQL_TYPES = { Types.OTHER }; 

    @Override 
    public int[] sqlTypes() { 
     return SQL_TYPES; 
    } 

    @SuppressWarnings("rawtypes") 
    @Override 
    public Class returnedClass() { 
     return Integer.class; 
    } 

    @Override 
    public boolean equals(Object x, Object y) throws HibernateException { 
     return x.equals(y); 
    } 

    @Override 
    public int hashCode(Object x) throws HibernateException { 
     return x.hashCode(); 
    } 

    @Override 
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) 
      throws HibernateException, SQLException { 
     String interval = rs.getString(names[0]); 
     if (rs.wasNull() || interval == null) { 
      return null; 
     } 
     PGInterval pgInterval = new PGInterval(interval); 
     Date epoch = new Date(0l); 
     pgInterval.add(epoch); 
     return Integer.valueOf((int)epoch.getTime()/1000); 
    } 

    public static String getInterval(int value){ 
     return new PGInterval(0, 0, 0, 0, 0, value).getValue(); 
    } 


    @Override 
    public void nullSafeSet(PreparedStatement st, Object value, int index) 
      throws HibernateException, SQLException { 
     if (value == null) { 
      st.setNull(index, Types.VARCHAR); 
     } else { 
      //this http://postgresql.1045698.n5.nabble.com/Inserting-Information-in-PostgreSQL-interval-td2175203.html#a2175205 
      st.setObject(index, getInterval(((Integer) value).intValue()), Types.OTHER); 
     } 
    } 

    @Override 
    public Object deepCopy(Object value) throws HibernateException { 
     return value; 
    } 

    @Override 
    public boolean isMutable() { 
     return false; 
    } 

    @Override 
    public Serializable disassemble(Object value) throws HibernateException { 
     return (Serializable) value; 
    } 

    @Override 
    public Object assemble(Serializable cached, Object owner) 
      throws HibernateException { 
     return cached; 
    } 

    @Override 
    public Object replace(Object original, Object target, Object owner) 
      throws HibernateException { 
     return original; 
    } 

} 
0

PostgreSQL có hàm date_part/extract mà bạn có thể sử dụng để trả về các giá trị khác nhau lĩnh vực, thời đại là một trong số họ. Khi trích xuất kỷ nguyên từ một khoảng thời gian, bạn nhận được số giây có trong khoảng thời gian đó và từ đó bạn có thể chuyển đổi theo ý muốn. Tôi đã mất kinh nghiệm với Hibernate, nhưng bạn có thể làm theo cách này:

SELECT 
    average_interval_between_airings 
    , date_part('epoch', average_interval_between_airings)/60 as minutes 
    , date_part('epoch', average_interval_between_airings) as seconds 
FROM shows; 
1

Tại sao không chỉ biến nó thành một số và ánh xạ dài?

SELECT EXTRACT(epoch FROM my_interval) 
Các vấn đề liên quan