使用CompositeUserType和使用UserType一样,但CompositeUserType多了HQL的查询支持,并相对比较复杂,一般使用UserType就足够了
使用UserType参考http://blog.csdn.net/daryl715/archive/2007/12/10/1927502.aspx
下面给出UserType不同的AddressType和测试代码:
package
Search.CompositeUserType;
import
java.io.Serializable;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.sql.Types;
import
org.apache.commons.lang.builder.EqualsBuilder;
import
org.apache.commons.lang.builder.HashCodeBuilder;
import
org.hibernate.Hibernate;
import
org.hibernate.HibernateException;
import
org.hibernate.engine.SessionImplementor;
import
org.hibernate.type.Type;
import
org.hibernate.usertype.CompositeUserType;
import
org.hibernate.usertype.UserType;
public
class
AddressType
implements
CompositeUserType, Serializable
...
{ private String homeAddr; private String workAddr; /**/ /* 获得属性名数组,属性名可用于进行HQL查询 */ public String[] getPropertyNames() ... { return new String[] ... { " homeAddr " , " schoolAddr " } ; } /**/ /* 获得对应的属性类型,必须和属性名数组元素的顺序相对应 */ public Type[] getPropertyTypes() ... { return new Type[] ... { Hibernate.STRING, Hibernate.STRING } ; } /**/ /* 通过index取得对象的属性值,index从0开始,顺序和配置文件中定义属性的顺序一致 */ public Object getPropertyValue(Object component, int property) throws HibernateException ... { AddressType address = (AddressType) component; if (property == 0 ) return address.getHomeAddr(); else return address.getWorkAddr(); } /**/ /* 根据index设置对象属性 */ public void setPropertyValue(Object component, int property, Object value) throws HibernateException ... { AddressType address = (AddressType) component; String add_value = (String)value; if (property == 0 ) address.setHomeAddr(add_value); else address.setWorkAddr(add_value); } /**/ /* 返回对应的映射类 */ public Class returnedClass() ... { return AddressType. class ; } /**/ /* 两个对象是否相等,使用了apache的common工具包来进行属性比对 */ public boolean equals(Object x, Object y) throws HibernateException ... { if (x == y) return true ; if (x == null || y == null ) return false ; AddressType add1 = (AddressType) x; AddressType add2 = (AddressType) y; return new EqualsBuilder() // 使用EqualsBuilder类来方便地进行比对 .append(add1.getHomeAddr(), add2.getHomeAddr()) .append(add2.getWorkAddr(), add2.getWorkAddr()) .isEquals(); } /**/ /* 得到hash码 */ public int hashCode(Object x) throws HibernateException ... { AddressType address = (AddressType) x; return new HashCodeBuilder() // 使用HashCodeBuilder类来方便地进行比对 .append(address.getHomeAddr()).append(address.getWorkAddr()) .toHashCode(); } /**/ /* 读取数据并组装成一个AddressType对象。names[]中的参数顺序依照映射文件中定义的顺序 */ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException ... { if (rs.wasNull()) return null ; String homeAddr = rs.getString(names[ 0 ]); String schoolAddr = rs.getString(names[ 1 ]); AddressType address = new AddressType(homeAddr, schoolAddr); return address; } /**/ /* 保存数据,index的顺序按照映射文件定义的顺序,从0开始。 */ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException ... { AddressType address = (AddressType) value; if (value == null ) ... { st.setNull(index, Types.VARCHAR); st.setNull(index + 1 , Types.VARCHAR); } else ... { st.setString(index, address.getHomeAddr()); st.setString(index + 1 , address.getWorkAddr()); } System.out.println(" Data has been saved! " ); } /**/ /* 完整拷贝一个对象,而不是直接返回它的引用 */ public Object deepCopy(Object value) throws HibernateException ... { if (value == null ) return null ; AddressType address = (AddressType) value; return new AddressType(address.getHomeAddr(), address.getWorkAddr()); } /**/ /* 设置类可变,可以通过属性的set方法改变属性值 */ public boolean isMutable() ... { return true ; } /**/ /* 当把AddressType类型数据写入二级缓存时,此方法被调用 */ public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException ... { return (Serializable) deepCopy(value); } /**/ /* 当从二级缓存中读取AddressType类型数据时,此方法被调用 */ public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException ... { return deepCopy(cached); } public Object replace(Object original, Object target, SessionImplementor session, Object owner) throws HibernateException ... { // TODO 自动生成方法存根 return null ; } /** */ /** ------------------------构造函数和get、set方法----------------- */ public AddressType(String homeAddr, String workAddr) ... { super (); this .homeAddr = homeAddr; this .workAddr = workAddr; } public AddressType() ... { super (); } public String getHomeAddr() ... { return homeAddr; } public String getWorkAddr() ... { return workAddr; } public void setWorkAddr(String workAddr) ... { this .workAddr = workAddr; } public void setHomeAddr(String homeAddr) ... { this .homeAddr = homeAddr; } }
测试代码:
package
Search.CompositeUserType;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileNotFoundException;
import
java.io.IOException;
import
java.sql.Blob;
import
java.sql.Clob;
import
org.hibernate.Hibernate;
import
org.hibernate.Session;
import
org.hibernate.SessionFactory;
import
org.hibernate.Transaction;
import
org.hibernate.cfg.Configuration;
public
class
Test
...
{ public static void main(String[] args) ... { String filePath = System.getProperty( " user.dir " ) + File.separator + " src/Search/CompositeUserType " + File.separator + " hibernate.cfg.xml " ; File file = new File(filePath); SessionFactory sessionFactory = new Configuration().configure(file).buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); AddressType address = new AddressType( " home " , " work " ); Student stu = new Student(); stu.setName( " tome1 " ); stu.setAddress(address); session.save(stu); // 测试CompositeUserType对HQL的支持 Student student = (Student)session.createQuery( " from Student s where s.address.homeAddr='home' " ).uniqueResult(); System.out.println(stu.getAddress().getHomeAddr() + " - " + student.getAddress().getWorkAddr()); tx.commit(); } }
运行结果:红色部分为HQL的支持效果
Hibernate: insert into typestu (name, homeaddr, workaddr, id) values (?, ?, ?, ?) Data has been saved! Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.homeaddr as homeaddr0_, student0_.workaddr as workaddr0_ from typestu student0_ where student0_.homeaddr='home' home-work