說明:由於Hibernate並沒有提供特殊的原生類別當作Mapping欄位(如我們需要List集合之類別),故Hibernate提供一個UserType Interface讓我們自己實作一個UserType。 實作方法如下:1.於t_user表格中加入一個email欄位,此email儲存資料的方式是以分號";"加以分隔,t_user表格schema如下:
drop table if exists t_user;create table t_user(id int(11) auto_increment,name varchar(50) not null default '',age int(3),version int(4),email varchar(300),primary key (id));
package org.redsaga.usertype;import java.util.List;import java.util.ArrayList;import java.io.Serializable;import java.sql.Types;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.hibernate.Hibernate;import org.hibernate.HibernateException;import org.hibernate.usertype.UserType;public class EMailList implements Serializable,UserType {private static final char SPLITTER=';';private static final int[] TYPES = new int[]{Types.VARCHAR};public boolean isMutable(){return false;}public int[] sqlTypes(){return TYPES;}public Class returnedClass(){return List.class;}/*** 建立一個新的List實例,包含原有List實例中的所有元素*/public Object deepCopy(Object value)throws HibernateException{List sourceList = (List)value;List targetList = new ArrayList();targetList.addAll(sourceList);return targetList;}/*** 判斷email list是否發生改變*/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;}else{return false;}}/*** 將以";"分隔的字串解析為一個字串陣例** @param value* @return List*/public List parse(String value){String[] strs = org.apache.commons.lang.StringUtils.split(value, SPLITTER);List emailList = new ArrayList();for(int i=0;i<strs.length;i++){emailList.add(strs[i]);}return emailList;}/*** 將String拼裝為一個字串,以";"分隔巷*/public String assemble(List emailList){StringBuffer strBuf = new StringBuffer();for(int i=0;i<emailList.size()-1;i++){strBuf.append(emailList.get(i)).append(SPLITTER);}strBuf.append(emailList.get(emailList.size()-1));return strBuf.toString();}/*** 從ResultSet中取出email欄位,並將其解析為List類型後回傳*/public Object nullSafeGet(ResultSet rs, String[] names, Object owner)throws HibernateException,SQLException{System.out.println("nullSafeGet method executed");String value = (String)Hibernate.STRING.nullSafeGet(rs, names[0]);if(value!=null){return parse(value);}else{return null;}}/*** 將List型的email資訊組裝成字串之後保存到email欄位*/public void nullSafeSet(PreparedStatement st, Object value, int index)throws HibernateException,SQLException{System.out.println("nullSafeSet method executed");if(value!=null){String str = assemble((List)value);Hibernate.STRING.nullSafeSet(st, str, index);}else{Hibernate.STRING.nullSafeSet(st, value, index);}}public Object assemble(Serializable cached, Object owner)throws HibernateException{return null;}public Serializable disassemble(Object value)throws HibernateException{return null;}public int hashCode(Object x)throws HibernateException{return 0;}public Object replace(Object original, Object target, Object owner)throws HibernateException{return null;}}=======================================3.TUser.java及TUser.hbm.xml內容如下:package org.redsaga.quickstart;// Generated 2009/8/6 下午 11:08:15 by Hibernate Tools 3.2.4.GAimport java.util.List;/*** TUser generated by hbm2java*/public class TUser implements java.io.Serializable {private Integer id;private Integer version;private String name;private Integer age;private List email;public TUser() {}public TUser(String name) {this.name = name;}public TUser(String name, Integer age, List email) {this.name = name;this.age = age;this.email = email;}public Integer getId() {return this.id;}public void setId(Integer id) {this.id = id;}public Integer getVersion() {return this.version;}public void setVersion(Integer version) {this.version = version;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public Integer getAge() {return this.age;}public void setAge(Integer age) {this.age = age;}public List getEmail() {return this.email;}public void setEmail(List email) {this.email = email;}}=========================================<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2009/8/6 ?U?? 11:08:15 by Hibernate Tools 3.2.4.GA --><hibernate-mapping><class name="org.redsaga.quickstart.TUser" table="t_user" catalog="manning"><id name="id" type="java.lang.Integer"><column name="id" /><generator class="identity" /></id><version name="version" type="java.lang.Integer"><column name="version" /></version><property name="name" type="string"><column name="name" length="50" not-null="true" /></property><property name="age" type="java.lang.Integer"><column name="age" /></property><property name="email" type="org.redsaga.usertype.EMailList"><column name="email" length="300" /></property></class></hibernate-mapping>==========================================4.Hibernate.cfg.xml,內容如下:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property><property name="hibernate.connection.password">action</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/manning</property><property name="hibernate.connection.username">manning</property><property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property><!-- 將SQL輸出到Console --><property name="hibernate.show_sql">true</property><!-- 使用JDBC Transaction --><property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property><!-- 將TUser.hbm.xml加到Hibernate.cfg.xml檔案中 --><mapping resource="org/redsaga/quickstart/TUser.hbm.xml"/></session-factory></hibernate-configuration>======================================5.利用JUnit建立一個測試method(testUserType),內容如下:/** * testUserType 測試UserType for email欄位是否有效 * @throws Exception */ public void testUserType() throws Exception { TUser user=null; Transaction tran = null; String hql = " from TUser where name='Emma'"; try{ tran = session.beginTransaction(); List emailList = new ArrayList(); user = new TUser(); user.setName("Emma"); user.setAge(19); emailList.add("Emma@org.redsaga"); emailList.add("Emma@yahoo.com.tw"); user.setEmail(emailList); session.save(user); session.flush(); tran.commit(); List userList = session.createQuery(hql).list(); //添加一個Email後保存 for(int i=0;i<userList.size();i++){ user = (TUser)userList.get(i); System.out.println(user.getEmail()); } }catch(HibernateException e){ e.printStackTrace(); } }==========================================6.測試結果:console輸出結果:Hibernate: insert into manning.t_user (version, name, age, email) values (?, ?, ?, ?)nullSafeSet method executedHibernate: select tuser0_.id as id0_, tuser0_.version as version0_, tuser0_.name as name0_, tuser0_.age as age0_, tuser0_.email as email0_ from manning.t_user tuser0_ where tuser0_.name='Emma'[Emma@org.redsaga, Emma@yahoo.com.tw]
2009年8月7日 星期五
Hibernate實作UserType之例子
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言