现在的位置: 首页 > 综合 > 正文

实现CompositeUserType接口

2014年03月03日 ⁄ 综合 ⁄ 共 5215字 ⁄ 字号 评论关闭

Hibernate还提供了一个CompositeUserType借口,它不仅能完成和UserType相同的功能,而且还提供了对Hibernate查询语言(HQL)的支持.下面通过例子来介绍CompositeUserType接口的方法.

假定在Customer类中包含了一个Name类型的name属性,代表客户的姓名.例1是Name类的源程序.

例1:

package mypack;

import java.io.Serializable;

/**
 * @author lfm
 *
 */
public class Name implements Serializable {

 private String firstname;

 private String lastName;

 public Name(String firstname, String lastName) {
  super();
  // TODO 自动生成构造函数存根
  this.firstname = firstname;
  this.lastName = lastName;
 }

 public String getFirstname() {
  return firstname;
 }

 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public boolean equals(Object o) {
  if (this == o)
   return true;
  if (!(o instanceof Name))
   return false;
  final Name name = (Name) o;
  return firstname.equals(name.firstname)
    && lastName.equals(name.lastName);
 }

 public int hashCode() {
  int result;
  result = (firstname == null ? 0 : firstname.hashCode());
  result = 29 * result + (lastName == null ? 0 : lastName.hashCode());
  return result;
 }

 public String toString() {
  return lastName + " " + firstname;
 }
}

从例1看出,Name类是可变类.因此,如果需要修改Customer对象的 name 属性,只需调用Name类的setFirstname()和setLastname()方法:

customer.setName(new Name("Lsosan", "Zhang"));

//修改Customer对象的name属性

customer.getName().setFirstname("Lsosi");

customer.getName().setLastname("Li");

接下来创建NameCompositeUserType类,它负责把Customer类的Name类型的属性映射到CUSTOMERS表的FIRSTNAME和LASTNAME字段.例2是NameCompositeUserType类的源程序.

例2:

package mypack;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import net.sf.hibernate.CompositeUserType;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;

/**
 * @author lfm
 *
 */
public class NameCompositeUserType implements CompositeUserType {

 /**
  * 返回Name类的所有属性的名字
  */
 public String[] getPropertyNames() {
  // TODO 自动生成方法存根
  return new String[] { "firstname", "lastname" };
 }

 /**
  * 返回Name类的所有属性的Hibernate映射类型
  */
 public Type[] getPropertyTypes() {
  // TODO 自动生成方法存根
  return new Type[] { Hibernate.STRING, Hibernate.STRING };
 }

 /**
  * 获取Name队形的某个属性的值。参数component代表Name对象,参数property代表属性在Name对象中的位置
  */
 public Object getPropertyValue(Object component, int property)
   throws HibernateException {
  // TODO 自动生成方法存根
  Name name = (Name) component;
  String result;
  switch (property) {
  case 0:
   result = name.getFirstname();
   break;
  case 1:
   result = name.getLastName();
  default:
   throw new IllegalArgumentException("unknow property: " + property);
  }
  return result;
 }

 /**
  * 设置Name对象的某个属性的值。参数component代表Name对象,参数property代表属性在Name对象中的位置,参数value代表属性值
  */
 public void setPropertyValue(Object component, int property, Object value)
   throws HibernateException {
  // TODO 自动生成方法存根
  Name name = (Name) component;
  String nameValue = (String) value;
  switch (property) {
  case 0:
   name.setFirstname(nameValue);
   break;
  case 1:
   name.setLastName(nameValue);
  default:
   throw new IllegalArgumentException("unknow property: " + property);
  }
 }

 /**
  * 设置NameCompositeUserType所映射的Java类:Name类
  */
 public Class returnedClass() {
  // TODO 自动生成方法存根
  return Name.class;
 }

 public boolean equals(Object x, Object y) throws HibernateException {
  // TODO 自动生成方法存根
  if (x == y)
   return true;
  if (x == null || y == null)
   return false;
  return x.equals(y);
 }

 public Object nullSafeGet(ResultSet rs, String[] names,
   SessionImplementor session, Object owner)
   throws HibernateException, SQLException {
  // TODO 自动生成方法存根
  if (rs.wasNull())
   return null;
  String firstname = rs.getString(names[0]);
  String lastname = rs.getString(names[1]);
  return new Name(firstname, lastname);
 }

 public void nullSafeSet(PreparedStatement statement, Object value,
   int index, SessionImplementor session) throws HibernateException,
   SQLException {
  // TODO 自动生成方法存根
  if (value == null)
   statement.setNull(index, Types.VARCHAR);
  else {
   Name name = (Name) value;
   statement.setString(index, name.getFirstname());
   statement.setString(index + 1, name.getLastName());
  }
 }

 /*
  * (非 Javadoc)
  *
  * @see net.sf.hibernate.CompositeUserType#deepCopy(java.lang.Object)
  */
 public Object deepCopy(Object value) throws HibernateException {
  // TODO 自动生成方法存根
  if (value == null)
   return null;
  Name name = (Name) value;
  return new Name(name.getFirstname(), name.getLastName());
 }

 /*
  * (非 Javadoc)
  *
  * @see net.sf.hibernate.CompositeUserType#isMutable()
  */
 public boolean isMutable() {
  // TODO 自动生成方法存根
  return true;
 }

 /**
  * 创建一格序列化的Name对象,Hibernate将把它保存到缓存中
  */
 public Serializable disassemble(Object value, SessionImplementor session)
   throws HibernateException {
  // TODO 自动生成方法存根
  return (Serializable) deepCopy(value);
 }

 /**
  * 根据缓存中的序列化的Name对象,重新构建一个Name对象,参数cached代表缓存中的序列化的Name对象
  */
 public Object assemble(Serializable cached, SessionImplementor session,
   Object owner) throws HibernateException {
  // TODO 自动生成方法存根
  return deepCopy(cached);
 }
}

从例2看出,CompositeUserType包含了UserType接口的大部分方法,此外,它还包含了用来访问Name类的所有属性的方法,getPropertyNames(),getPropertyTypes(),getPropertyValue(),setPropertyValue()

在Customer.hbm.xml文件中,以下代码用于把Name类型的name属性映射到CUSTOMERS表的FIRSTNAME和LASTNAME字段:

<property name="name" type="mypack.NameCompositeUserType">

  <column name="FIRSTNAME" length="15"/>

  <column name="LASTNAME" length="15"/>

</property>

在应用程序中创建HQL语句时,可以通过"c.name.firstname"的形式访问Customer的name属性的firstname属性:

Customer customer = session.find("from Customer as c where c.name.firstname='Tom'");

抱歉!评论已关闭.