1. 程式人生 > >使用Hibernate的XML配置來對映列舉型別,儲存自定義型別資料

使用Hibernate的XML配置來對映列舉型別,儲存自定義型別資料

   如今使用Hibernater作為ORM框架時,幾乎都是採用註解方式進行對映,可以對映任何型別欄位。這裡要說的是
對映列舉型別,在註解的方式下很容易(以後再補充),但是xml配置下就顯得麻煩一點。更復雜的一種對映,就是
列舉型別儲存到資料庫中的型別不是字串本身,也不是ordinal,即自定義型別資料儲存。   

   以下以自定義型別為Integer(即儲存在資料庫中的是Integer型別)為例:

 1. 首先建立列舉型別介面
public interface EnumsID {
    String getText();
    Integer getId();
}

裡面定義的getId()就是我們要儲存到資料庫中的資料型別

2.定義列舉型別(繼承上面介面)
public enum Gender implements EnumsID{
    MALE(1, "男"),
    FEMALE(2, "女");

    private Integer id;
    private String text;

    private Gender(Integer id,String text){
        this.id = id;
        this.text = text;
    }
    @Override
    public String getText() {
        return
text; } @Override public Integer getId() { return id; } public static Gender findById(Integer id) { Gender[] objs = Gender.values(); for (Gender obj : objs) { if (id.equals(obj.getId())) { return obj; } } return
null; } }
 3.編寫一個轉換模板,實現UserType型別介面,將列舉型別轉換為Integer型別儲存到資料庫
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.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

public class IntegerEnumUserType<E extends Enum<E>> implements UserType {

    private Class<E> clazz = null;

    protected IntegerEnumUserType(Class<E> c) {
        this.clazz = c;
    }

    private static final int[] SQL_TYPES = { Types.INTEGER };

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

    @Override
    public Class<E> returnedClass() {
        return clazz;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        if (x == y)
            return true;
        if (null == x || null == y)
            return false;
        return x.equals(y);
    }

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

    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        final int id = resultSet.getInt(names[0]);
        if (!resultSet.wasNull()) {
            try {
                return clazz.getMethod("findById", new Class[] { Integer.class }).invoke(null, id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor session)
            throws HibernateException, SQLException {
        if (null == value) {
            preparedStatement.setNull(index, SQL_TYPES[0]);
        } else {
            EnumsID eID = (EnumsID) value;
            preparedStatement.setInt(index, eID.getId());
        }
    }

    @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;
    }

}
  4.建立具體類來實現當前列舉的轉換,需要繼承轉換模板
public class GenderEnum extends IntegerEnumUserType<Gender>{
    public GenderEnum() { 
        super(Gender.class); 
    } 
}
  5.在XML中對映列舉型別
<property name="gender" type="com.xxx..GenderEnum">
    <column name="gender">
        <comment>性別 1男,2女</comment>
    </column>
</property>
這樣就可以在實體中使用 Gender 這個列舉型別進行操作了。
public class User{
    private Integer id;
    private Gender gender;

    public Gender getGender() {
        return this.gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }
    ...
}

相關推薦

使用Hibernate的XML配置對映列舉型別儲存定義型別資料

如今使用Hibernater作為ORM框架時,幾乎都是採用註解方式進行對映,可以對映任何型別欄位。這裡要說的是 對映列舉型別,在註解的方式下很容易(以後再補充),但是xml配置下就顯得麻煩一點。更復雜的一種對映,就是 列舉型別儲存到資料庫中的型別不是字串本

知識點總結: c#使用定義型別作為Dictionary的Key

首先來看一個變數的定義: /// <summary> /// key依次是StationId,channelId,deviceId,paraType,dataId,dataTypeId,logicalDeviceIndex,paraHandle,

Qt中QVariant儲存定義型別

#include <QDebug> //先宣告類 class Test{ public: QString myName; }; //註冊自定義型別 Q_DECLARE_METATYPE(Test) int main(int argc, char *argv[]) {

MyBatis配置typeHandler型別轉換器 (定義型別轉換器)

MyBatis配置のtypeHandler型別轉換器 - 簡書 https://www.jianshu.com/p/8e0a2d06892c     初始typeHandler 在JDBC中,需要在PreparedStatement物件中設定那些已經預編譯過的

logback系列之七:繼承RollingFileAppender儲存定義檔名的日誌

繼承類:package com.hk3t.air.system.log; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos

Redis 儲存定義資料型別

Redis自帶的基本型別的操作可以自行查閱資料,網上可以輕易找到很多的相關的資料。 儲存自定義型別時需要進行序列化、反序列化。 1. Java示例程式碼 //定義需要儲存的資料 Student

Object型別轉換成定義型別(向下轉型)

Object型別轉換成自定義型別 場景:   從資料庫或者別的途徑接收物件的時候用Object,但是用的時候怎麼object點(方法提示 | alt+'/'),都點不出自定義型別的方法。   比如,資料庫查詢Customer的時候,用Object來接收,那麼想要呼叫Customer中的getCust_I

iOS--使用NSUserDefaults儲存定義模型資料

我們都用過NSUserDefaults來儲存資料,它是一個單例,在整個程式中只有一個例項物件,他可以用於資料的永久儲存,當我們只用來儲存登入的一些ID等資訊的時候,就沒必要搭建資料庫來儲存了,用NSUserDefaults就夠了,非常簡單實用,不必繁瑣的SQL語句,這也是大家

Groovy將字串型別轉換為定義型別的方法

    @Override     void build(val) {         if (val instanceof Quantity) {             this.amount = val.amount             this.uni

插入資料儲存的date型別時間欄位的資料只有年月日沒有時分秒的問題

本人使用的hibernate實體類對映方式,在實體類中date型別的註解方式,預設生成的是@Temporal(TemporalType.DATE) 在儲存的時候,此欄位資料就只保留了年月日 將註解方式更改為@Temporal(TemporalType.TIMESTAMP),就能正確儲存(

窗體背景的繪制(Windows窗體每次都會重繪其窗體背景所以我們可以通過攔截窗體重繪背景的消息(WM_ERASEBKGND)定義方法實現重繪窗體背景)

height com call 消息響應 int idt http msg mes 核心思想:由於Windows窗體每次都會重繪其窗體背景,所以我們可以通過攔截窗體重繪背景的消息(WM_ERASEBKGND),並自定義方法來實現重繪窗體背景。通過TImage組件也可以實現,

不要老盯著儲存儲存的價值在於資料流:Filenet

前言:近期,部分原IPFS開發者發起的共享儲存Filenet.io組織,推出了全新的IPFS激勵層Filenet,本著網際網路的本質是“流量”而不是儲存的理念,提出了全球首創的“檢索分發挖礦”口號,讓人不禁想起了年初ENU牛油果專案。 我的觀點:Filecoin很牛,但是區塊鏈的儲存如果僅僅停留

JAVA:HashMap常用方法對於定義類的儲存原始碼分析

public static void main(String[] args) { //hashMap儲存結構為陣列+連結串列 //資料儲存方式為鍵值對 HashMap<String, Integer> hashMap = ne

SpringBoot的定義配置方法一通過定義配置檔案

  自定義配置的目的:通過自定義屬性,注入到程式中使用,可以靈活的更改配置資訊,修改自定義屬性值,達到修改程式的目的。 一、新建一個SpringBoot工程,目錄結構如下:   其中MyConfig.java檔案內容為:@Component與@ConfigurationPrope

CentOS 7.x系統新增70-persistent-net.rules檔案實現網絡卡名稱定義

CentOS 7.x系統中網絡卡命名規則被重新定義,可能會是”eno167777xx”等,下面我們把網絡卡名稱改為eth0這種。 一、cd  /etc/sysconfig/network-scripts/  #進入網絡卡配置目錄 mv  eno16777736  ifcf

實現新增資料關聯其他類比如新增商品時需要商品型別如何關聯這些型別

後臺: $detail是編輯時的模板資料 $yccart = D('Elecate')->where(array('cate_id' => $detail['cate_id'])) ->find(); $this->assign('yccart', $yccart

jquery $.jBox彈窗 父窗體呼叫子窗體方法儲存子窗體頁面資料

//新增--以彈窗的方式                                父窗體 <script type="text/javascript"> $(document).ready(function() { $("#btnAdd").click

ArrayList儲存定義物件並遍歷要求加入泛型並用增強for遍歷

import java.util.ArrayList;import java.util.Iterator;public class ArrayListDemo1 {public static void

Java 往TreeSet集合中儲存定義物件學生按照學生的年齡進行排序。

Set:無序,不可以重複元素。|--HashSet:資料結構是雜湊表。執行緒是非同步的。保證元素唯一性的原理:判斷元素的hashCode值是否相同。如果相同,還會繼續判斷元素的equals方法,是否為true。|--TreeSet:可以對Set集合中的元素進行排序。底層資料

C語言定義型別:結構體、列舉、聯合

結構體 結構體的宣告 結構體的自引用 結構體變數的定義和初始化