Hibernate的強(qiáng)大用過(guò)的童鞋肯定會(huì)知道的,通過(guò)OR映射我們可以很方便的實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作,Hibernate對(duì)我們一些類(lèi)型的映射都提供了
很好的支持,但是顯然也有不給力的地方,比如簡(jiǎn)單的注冊(cè),一個(gè)人可能有好多郵箱,對(duì)于這個(gè)問(wèn)題怎么做呢?有人說(shuō)簡(jiǎn)單,可以另外開(kāi)一張表,恩,很不錯(cuò),確實(shí)
可以,可是這樣有時(shí)候可能小題大作了。也有人說(shuō),直接將郵箱拼接成字符串然后在存儲(chǔ),這個(gè)想法也很好,但在我們讀出來(lái)的時(shí)候就要再進(jìn)行一次解析操作,將
EMAIL還原,這些都要求我們編程人員自己完成。那么Hibernate有沒(méi)有提供什么好的支持呢?回答是肯定的,Hibernate給我們提供了一個(gè)
UserType接口,通過(guò)UserType我們可以對(duì)一些常見(jiàn)的類(lèi)型進(jìn)行封轉(zhuǎn),轉(zhuǎn)變成具有個(gè)性的類(lèi)型。下面我們就來(lái)體驗(yàn)一下吧:
債務(wù)追討
首先我么創(chuàng)建一個(gè)自定義類(lèi)型的類(lèi),讓他實(shí)現(xiàn)UserType接口:
/**
* @author :LYL
*@date:2011-4-26,下午08:39:42
*/
package com.lyl.hibernate.mytype;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import com.opensymphony.oscache.util.StringUtil;
public class ArrayType implements UserType{
private static final char Spliter=';';
/**
* 自定義類(lèi)型的完全復(fù)制方法,構(gòu)造返回對(duì)象
* 1. 當(dāng)nullSafeGet方法調(diào)用之后,我們獲得了自定義數(shù)據(jù)對(duì)象,在向用戶返回自定義數(shù)據(jù)之前
* deepCopy方法被調(diào)用,它將根據(jù)自定義數(shù)據(jù)對(duì)象構(gòu)造一個(gè)完全拷貝,把拷貝返還給客戶使用。
* 2.此時(shí)我們就得到了自定義數(shù)據(jù)對(duì)象的兩個(gè)版本
* 原始版本由hibernate維護(hù),用作臟數(shù)據(jù)檢查依據(jù),復(fù)制版本由用戶使用,hibernate將在
* 臟數(shù)據(jù)檢查過(guò)程中比較這兩個(gè)版本的數(shù)據(jù)。人人
*
*
*/
@Override
public Object deepCopy(Object value) throws HibernateException {
List source=(List)value;
List target=new ArrayList();
target.addAll(source);
return target;
}
/**
* 自定義數(shù)據(jù)類(lèi)型比對(duì)方法
* 用作臟數(shù)據(jù)檢查,X,Y為兩個(gè)副本
*/
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x==y) {
return true;
}
if(x!=null&&y!=null){
List xList=(List)x;
List ylList=(List)y;
if (xList.size()!=ylList.size()) {
return false;
}
for(int i=0;i<xList.size();i++){
String s1=(String)xList.get(i);
String s2=(String)ylList.get(i);
if (!s1.equals(s2)) {
return false;
}
}
return true;
}
return false;
}
/**
* 返回給定類(lèi)型的hashCode
*/
@Override
public int hashCode(Object value) throws HibernateException {
return value.hashCode();
}
/**
* 表示本類(lèi)型實(shí)例是否可變
*/
@Override
public boolean isMutable() {
// TODO Auto-generated method stub
return false;
}
/**
* 讀取數(shù)據(jù)轉(zhuǎn)換為自定義類(lèi)型返回
* names包含了自定義類(lèi)型的映射字段名稱(chēng)
*/
@SuppressWarnings("deprecation")
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
//取得字段名稱(chēng)并查詢
String value=(String)Hibernate.STRING.nullSafeGet(rs, names[0]);
if (value!=null) {
return parse(value);
}else {
return null;
}
}
/**
* 數(shù)據(jù)保存時(shí)被調(diào)用
*/
@Override
public void nullSafeSet(PreparedStatement ps, Object value, int index)
throws HibernateException, SQLException {
if(value!=null){
String str=combain((List)value);
//保存數(shù)據(jù)
Hibernate.STRING.nullSafeSet(ps, str,index);
}else {
//空值就直接保存了
Hibernate.STRING.nullSafeSet(ps,value.toString(),index);
}
}
/**
* 將數(shù)據(jù)解析為L(zhǎng)IST返回
* @param value
* @return
*/
private List parse(String value){
List list=StringUtil.split(value, Spliter);
return list;
}
private String combain(List list){
StringBuffer sb=new StringBuffer();
for(int i=0;i<list.size()-1;i++){
sb.append(list.get(i)).append(Spliter);
}
sb.append(list.get(list.size()-1));
return sb.toString();
}
/**
* 修改類(lèi)型對(duì)應(yīng)的java類(lèi)型
* 我們這邊使用LIST類(lèi)型
*/
@Override
public Class returnedClass() {
return List.class;
}
/**
* 修改類(lèi)型對(duì)應(yīng)的SQL類(lèi)型
* 使用VARCHAR
*/
@Override
public int[] sqlTypes() {
return new int[]{Types.VARCHAR};
}
@Override
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return null;
}
/**
* 不知干嘛用的
*/
@Override
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
return null;
}
@Override
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
}
然后我們?cè)谂渲肙R映射文件時(shí),指定一下自己的類(lèi)型:
<property name="emails" column="emails" type="com.lyl.hibernate.mytype.ArrayType"/>
posted on 2011-04-28 09:25
墻頭草 閱讀(3291)
評(píng)論(0) 編輯 收藏