主頁 > 知識庫 > Hibernate識別數(shù)據(jù)庫特有字段實例詳解

Hibernate識別數(shù)據(jù)庫特有字段實例詳解

熱門標(biāo)簽:電銷機器人免培訓(xùn) 電話機器人需要使用網(wǎng)絡(luò)嗎 如何看懂地圖標(biāo)注點 給地圖標(biāo)注得傭金 海外圖書館地圖標(biāo)注點 自繪地圖標(biāo)注數(shù)據(jù) 南通通訊外呼系統(tǒng)產(chǎn)品介紹 潤滑油銷售電銷機器人 外呼系統(tǒng)使用方法

Hibernate識別數(shù)據(jù)庫特有字段實例詳解

前言:

Hibernate已經(jīng)為絕大多數(shù)常用的數(shù)據(jù)庫數(shù)據(jù)類型提供了內(nèi)置支持,但對于某些數(shù)據(jù)庫的專屬字段支持就不夠好了。 這些特殊數(shù)據(jù)類型往往提供了比常規(guī)數(shù)據(jù)類型更好的數(shù)據(jù)表達(dá)能力,更符合我們的業(yè)務(wù)場景。比如PostgreSQL的Interval類型,可以非常方便的保存一個時間段的數(shù)據(jù)。 本文以添加Interval類型支持為例,說明為Hibernate添加特有數(shù)據(jù)類型支持的方法。
Hibernate提供了豐富的數(shù)據(jù)類型支持,但對于部分?jǐn)?shù)據(jù)庫專有的數(shù)據(jù)類型,提供的支持就很有限了。比如PostgreSQL的Interval類型,對于保存一個"時間段"數(shù)據(jù)就非常方便。

在開發(fā)中,我們期望將Interval類型映射為Java 8 的Duration類型。但是Hibernate默認(rèn)對Duration類型的映射是直接映射到數(shù)據(jù)庫的BigInt類型,直接保存納秒值。顯然對于不直接支持Interval類型的數(shù)據(jù)庫來說,是比較合適的,但是我們?nèi)匀黄谕苯佑成涞綌?shù)據(jù)庫的Interval類型。

為此,我們需要調(diào)整Hibernate對于兩種數(shù)據(jù)類型(Java世界的Duration和Db世界的Interval)的映射關(guān)系。

幸運的是,Hibernate提供了非常方便的方法可以實現(xiàn)數(shù)據(jù)類型的映射。

為此,我們需要一個實現(xiàn)org.hibernate.usertype.UserType接口的類,來實現(xiàn)兩個世界的數(shù)據(jù)轉(zhuǎn)換/映射工作。

Hibernate的自定義類型(UserType)

UserType是Hibernate提供的一個自定義數(shù)據(jù)類型的接口。所有自定義數(shù)據(jù)均需實現(xiàn)此接口,或者從org.hibernate.usertype中定義的接口中選擇一個合適的接口。

鑒于我們的場景比較簡單,直接實現(xiàn)UserType即可滿足需求。此接口提供了如下一組方法需要自己實現(xiàn):

assemble(Serializable cached, Object owner)

     從序列化中重新構(gòu)建(Java)對象。

deepCopy(Object value)

      返回深度副本。

disassemble(Object value)

     轉(zhuǎn)換對象的序列化數(shù)據(jù)。

equals(Object x, Object y)

     返回兩個映射的數(shù)據(jù)是否相等。

hashCode(Object x)

      獲取對象的散列。

isMutable()

      返回對象是否是可變類型。

nullSafeGet(ResultSet rs, String[] names, Object owner)

      從數(shù)據(jù)庫類型的數(shù)據(jù),返回對應(yīng)的Java對象。核心實現(xiàn)方法

nullSafeSet(PreparedStatement st, Object value, int index)

       從Java對象,返回對應(yīng)的數(shù)據(jù)庫類型的數(shù)據(jù)。核心實現(xiàn)方法

replace(Object original, Object target, Object owner)

       合并期間,將實體中的目標(biāo)值(target)替換為原始值(original)。

returnedClass()

      nullSafeGet返回的類。

sqlTypes()

       返回對應(yīng)的數(shù)據(jù)庫類型。

實例

package framework.postgresql;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import org.postgresql.util.PGInterval;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.Duration;

/**
 * PostgreSql Inteval字段與java.time.Duration映射
 * 目前只支持到最多1個月(30天)的間隔
 * p>
 * 使用方法:
 * 在實體類上增加
 * \@TypeDef(name="interval", typeClass = IntervalType.class)
 * 在字段定義上增加:
 * \@Type(type = "interval")
 * p>
 * http://stackoverflow.com/questions/1945615/how-to-map-the-type-interval-in-hibernate/6139581#6139581
 *
 * @version 1.0
 * @since 1.0
 */
public class IntervalType implements UserType {

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

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

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

 public boolean equals(Object arg0, Object arg1) throws HibernateException {
  return arg0 != null  arg1 != null  arg0.equals(arg1) || arg0 == null  arg1 == null;
 }

 public int hashCode(Object object) throws HibernateException {
  return object.hashCode();
 }


 @Override
 public Object nullSafeGet(ResultSet resultSet, String[] names, SharedSessionContractImplementor sessionImplementor, Object o) throws HibernateException, SQLException {
  String interval = resultSet.getString(names[0]);
  if (resultSet.wasNull() || interval == null) {
   return null;
  }
  PGInterval pgInterval = new PGInterval(interval);

  return getDuration(pgInterval);
 }

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

 public static Duration getDuration(PGInterval pgInterval) {
  return Duration.ofSeconds(pgInterval.getDays() * 24 * 3600 +
    pgInterval.getHours() * 3600 +
    pgInterval.getMinutes() * 60 +
    (int) pgInterval.getSeconds());
 }

 private static PGInterval getInterval(Duration value) {
  long seconds = value.getSeconds();
  int days = (int) (seconds / (24 * 3600));
  seconds -= days * 24 * 3600;
  int hours = (int) (seconds / 3600);
  seconds -= hours * 3600;
  int minutes = (int) (seconds / 60);
  seconds -= minutes * 60;
  seconds = Math.abs(seconds);
  return new PGInterval(0, 0, days, hours, minutes, seconds);
 }


 public boolean isMutable() {
  return false;
 }


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

 public Class returnedClass() {
  return Duration.class;
 }

 public int[] sqlTypes() {
  return new int[]{Types.OTHER};
 }

}

使用自定義類型

至此,我們已經(jīng)定義好了自己的數(shù)據(jù)類型。但Hibernate還不知道怎么使用它。為此,我們需要通過在Entity上使用使用TypeDef注解,并在屬性上使用Type注解。

比如:

...
@Entity
@TypeDef(name = "interval", typeClass = IntervalType.class)
public class PaperStatis implements Serializable {
...
 @Column(name = "avg_duration")
 @Type(type = "interval")
 public Duration getAvgDuration() {
  return this.avgDuration;
 }
...
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

您可能感興趣的文章:
  • Hibernate迫切連接和普通連接的區(qū)別實例詳解
  • hibernate通過session實現(xiàn)增刪改查操作實例解析
  • 在已有spring的基礎(chǔ)上集成hibernate的實例講解
  • hibernate屬性級別注解實例代碼
  • Hibernate 修改數(shù)據(jù)的實例詳解
  • JSP開發(fā)之hibernate之單向多對一關(guān)聯(lián)的實例
  • hibernate4快速入門實例詳解
  • Hibernate初體驗及簡單錯誤排除代碼詳解

標(biāo)簽:貸款邀約 南京 樂山 大連 黃石 內(nèi)江 銅川 廣州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Hibernate識別數(shù)據(jù)庫特有字段實例詳解》,本文關(guān)鍵詞  Hibernate,識別,數(shù)據(jù)庫,特有,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Hibernate識別數(shù)據(jù)庫特有字段實例詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于Hibernate識別數(shù)據(jù)庫特有字段實例詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章