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'");
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lifaming15/archive/2007/06/23/1663786.aspx
分享到:
相关推荐
此外,还可以通过实现UserType和CompositeUserType接口自定义数据映射。 5. **可扩展接口** - **Dialect**:这是Hibernate的方言抽象类,为不同的数据库系统(如Oracle、MSSQL、Sybase)提供了特定的方言实现,以...
2. 实现`CompositeUserType`接口:这个接口适用于处理复合类型,即一个对象由多个字段组成,每个字段都有自己的数据类型。`CompositeUserType`需要实现的方法包括`propertyNames()`、`propertyTypes()`、`...
也可以通过实现 org.hibernate.usertype.CompositeUserType 接口来自定义数据映射类型。 可扩展接口 1. org.hibernate.usertype.UserType:可以自定义数据映射类型。 2. org.hibernate.dialect.Dialect abstract_...
2. **实现Hibernate用户类型接口**:自定义类型需要实现`org.hibernate.usertype.UserType`接口。这个接口要求我们重写一些关键方法,如`nullSafeGet()`、`nullSafeSet()`、`equals()`、`hashCode()`等,以便...
11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类对应一个表 12.1.1 创建映射文件 ...
11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类对应一个表 12.1.1 创建映射文件 ...
11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类对应一个表 12.1.1 创建映射文件 ...
11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类对应一个表 12.1.1 创建映射文件 ...
7. **类型转换**:`UserType`和`CompositeUserType`接口允许自定义Java类型与数据库类型的转换。 8. **元数据获取**:`ClassMetadata`和`SessionFactoryMetadata`等接口提供了获取关于实体类和整个SessionFactory的...
16.2.2 实现泛型CRUD接口 16.2.3 实现实体DAO 16.2.4 利用数据访问对象 16.3 命令模式简介 16.3.1 基础接口 16.3.2 执行命令对象 16.3.3 命令模式的变形 16.4 利用EJB 3.0设计应用...
- **基本API**: Session、SessionFactory、Transaction等核心接口的使用。 - **JMX集成**: 如何将Hibernate与JMX集成,以便监控和管理。 - **上下文会话**: 管理会话的生命周期,以及与线程的绑定。 #### 3. 配置 ...
如果内置的映射类型无法满足需求,开发者可以通过实现 `net.sf.hibernate.UserType` 或 `net.sf.hibernate.CompositeUserType` 接口来自定义映射类型。自定义映射类型允许开发者将任何Java类映射到数据库的特定类型...