Hibernate映射自定義數(shù)據(jù)類型
數(shù)據(jù)庫(kù)中存在一個(gè)email字段,并允許其中存儲(chǔ)多個(gè)email地址,各地址之間使用 ; 分割,但是在POJO中,為了便于處理,email定義為一個(gè)List對(duì)象。
如何將String字段映射為L(zhǎng)ist類型,Hibernate并沒(méi)有提供原生支持,需要我們實(shí)現(xiàn)自己的UserType。
1.數(shù)據(jù)庫(kù)定義
CREATE TABLE t_user_mail (
id INT NOT NULL AUTO_INCREMENT
, name VARCHAR ( 50 )
, age INT
, email VARCHAR ( 300 )
, PRIMARY KEY (id)
);
2.
實(shí)現(xiàn)了UserType的自定義數(shù)據(jù)類型類EMailList
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.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class EMailList implements UserType {
private static final char SPLITTER = ' ; ' ;
private static final int [] TYPES = new int [] {Types.VARCHAR};
public int [] sqlTypes() {
// TODO Auto-generated method stub
return TYPES;
}
public Class returnedClass() {
// TODO Auto-generated method stub
return List. class ;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) return true ;
if (x != null & y != null ) {
List xlist = (List)x;
List ylist = (List)y;
if (xlist.size() != ylist.size()) return false ;
for ( int i = 0 ; i < xlist.size(); i ++ ) {
String str1 = (String)xlist.get(i);
String str2 = (String)ylist.get(i);
if ( ! str1.equals(str2)) return false ;
}
return true ;
}
return false ;
}
public int hashCode(Object arg0) throws HibernateException {
// TODO Auto-generated method stub
return 0 ;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
String value = (String)Hibernate.STRING.nullSafeGet(rs, names[ 0 ]);
if (value != null ) {
return parse(value);
} else {
return null ;
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value != null ) {
String str = assemble((List)value);
Hibernate.STRING.nullSafeSet(st, str, index);
} else {
Hibernate.STRING.nullSafeSet(st, value, index);
}
}
public Object deepCopy(Object value) throws HibernateException {
List sourceList = (List)value;
List targetList = new ArrayList();
targetList.addAll(sourceList);
return targetList;
}
public boolean isMutable() {
// TODO Auto-generated method stub
return false ;
}
public Serializable disassemble(Object arg0) throws HibernateException {
// TODO Auto-generated method stub
return null ;
}
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
// TODO Auto-generated method stub
return null ;
}
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
// TODO Auto-generated method stub
return null ;
}
private String assemble(List emailList) {
StringBuffer strBuf = new StringBuffer();
for ( int i = 0 ; i < emailList.size() - 1 ; i ++ ) {
strBuf.append((String)emailList.get(i)).append(SPLITTER);
}
strBuf.append(emailList.get(emailList.size() - 1 ));
return strBuf.toString();
}
private List parse(String value) {
String[] strs = StringUtils.split(value, SPLITTER);
List emailList = new ArrayList();
for ( int i = 0 ; i < strs.length; i ++ ) {
emailList.add(strs[i]);
}
return emailList;
}
}
3.
配置文件TUserMail.hbm.xml

























4.
在hibernate.cfg.xml載入TUserMail.hbm.xml
















5.
測(cè)試類HibernateTest.java
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateTest extends TestCase {
Session session = null;
/**
* JUnit中的setUp方法在TestCase初始化的時(shí)候會(huì)自動(dòng)調(diào)用
* 一般用于初始化公用資源
*/
protected void setUp() {
try {
/**
* 可以采用hibernate.properties或者h(yuǎn)ibernate.cfg.xml
* 配置文件的初始化代碼
*
* 采用hibernate.properties
* Configuration config = new Configuration();
* config.addClass(TUser.class);
*/
//采用hibernate.cfg.xml配置文件,與上面的方法對(duì)比,兩個(gè)差異
//1.Configuration的初始化方式
//2.xml
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
} catch (HibernateException e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* JUnit中的tearDown方法在TestCase執(zhí)行完畢的時(shí)候會(huì)自動(dòng)調(diào)用
* 一般用于釋放資源
*/
protected void tearDown() {
try {
session.close();
} catch (HibernateException e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 對(duì)象持久化測(cè)試(Insert方法)
*/
public void testInsert() {
Transaction tran = null;
try {
tran = session.beginTransaction();
TUserMail user = new TUserMail();
user.setName("byf");
List list = new ArrayList();
list.add("baiyf@msn.com");
list.add("bexy@163.com");
user.setEmail(list);
session.save(user);
session.flush();
tran.commit();
Assert.assertEquals(user.getId().intValue()>0 ,true);
} catch (HibernateException e) {
// TODO: handle exception
e.printStackTrace();
Assert.fail(e.getMessage());
if(tran != null) {
try {
tran.rollback();
} catch (Exception e1) {
// TODO: handle exception
e1.printStackTrace();
}
}
}
}
/**
* 對(duì)象讀取測(cè)試(Select方法)
*/
public void testSelect(){
String hql = " from TUserMail where name='byf'";
try {
List userList = session.createQuery(hql).list();
TUserMail user = (TUserMail)userList.get(0);
List mailList = user.getEmail();
Assert.assertEquals((String)mailList.get(0), "baiyf@msn.com");
Assert.assertEquals((String)mailList.get(1), "bexy@163.com");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
}
運(yùn)行測(cè)試代碼,觀察數(shù)據(jù)庫(kù)中,可以發(fā)現(xiàn)email地址信息已經(jīng)以";"分隔的形式保存。同時(shí),在數(shù)據(jù)讀取時(shí),我們也無(wú)需面對(duì)原始的";"分隔字符串,轉(zhuǎn)而只需要處理List類型數(shù)據(jù)即可。
posted on 2006-06-29 16:36 baim 閱讀(1966) 評(píng)論(2) 編輯 收藏 所屬分類: 開(kāi)源軟件框架