Hibernate提供了客户化映射类型接口,允许用户以编程的方式创建自定义的映射类型,以便把持久化类的任意类型的属性映射到数据库中.例1的PhoneUserType实现了net.sf.hibernate.UserType接口,它能够把Customer类的Integer类型的phone属性映射到CUSTOMER表的VARCHAR类型的PHONE字段.
例1:
package mypack;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.UserType;
/**
* @author lfm
*
*/
public class PhoneUserType implements UserType {
private static final int[] SQL_TYPES = {Types.VARCHAR};
public int[] sqlTypes() {
// TODO 自动生成方法存根
return SQL_TYPES;
}
public Class returnedClass() {
// TODO 自动生成方法存根
return Integer.class;
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
// TODO 自动生成方法存根
if(resultSet.wasNull())
return null;
String phone = resultSet.getString(names[0]);
return new Integer(phone);
}
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
// TODO 自动生成方法存根
if(value== null)
arg0.setNull(index, Types.VARCHAR);
else {
String phone = ((Integer)value).toString();
statement.setString(index, phone);
}
}
public Object deepCopy(Object value) throws HibernateException {
// TODO 自动生成方法存根
return value;
}
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 boolean isMutable() {
// TODO 自动生成方法存根
return false;
}
}
PhoneUserType实现了net.sf.hibernate.UserType接口中的所有方法,下面解释这些方法的作用.
(1)设置CUSTOMERS表的PHONE字段SQL类型,它是VARCHAR类型:
private static final int[] SQL_TYPES = {Types.VARCHAR};
public int[] sqlTypes() {return SQL_TYPES;}
(2)设置Customer类的phone属性的Java类型,它是Integer类型:
public CLass returnedClass() {return Integer.class;}
(3)Hibernate调用isMutable()方法来了解Integer类是否是可变类.本例的Integer类是不可变类,因此返回false.Hibernate处理不可变属性类型的属性时,会采取一些性能优化措施.
public boolean isMutable() {return false;}
(4)Hibernate调用deepCopy(Object value)方法来生成phone属性的快照.deepCopy()方法的value参数代表Integer类型的phone属性.由于Integer类是不可变类,因此本方法直接返回参数:
public Object deepCopy(Object value) {
return value;
}
对于可变类,必须返回参数的拷贝值.后面会说.
(5)Hibernate调用equals(Object x, Object y)方法类比较Customer类的phone属性的当前值是否和它的快照相同.该方法的一个参数代表phone属性的当前值,一个参数代表由deepCopy()方法生成的phone属性的快照:
public boolean equals(Object x, Object y) {
if(x== y)
return true;
if(x== null || y== null)
return false;
return x.equals(y);
}
(6)当Hibernate从数据库加载Customer对象时,调用nullSafeGet()方法类取得phone属性值.参数resultSet为JDBC查询结果集,参数names为存放了表字段名的数组,此处为{"PHONE"},参数owner代表phone属性的宿主,此处为Customer对象.
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException,SQLException {
if(resultSet.wasNull()) return null;
String phone = resultSet.getString(names[0]);
return new Integer(phone);
}
在nullSafeGet方法中,先从ResultSet从读取PHONE字段的值,然后把它转换为Integer对象,最后将它作为phone属性值返回.
(7)当Hibernate把Customer对象持久化到数据库中时,调用nullSafeSet()方法来把phone属性添加到INSERT SQL语句中.statement参数包含了预定义的INSERT SQL语句,参数value代表phone属性,参数index代表把phone属性插入到INSERT SQL语句中的位置:
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
if(value == null) {
statement.setNull(index, Types.VARCHAR);
}else{
String phone = ((Integer)value).toString();
statement.setString(index, phone);
}
}
在nullSafeSet()方法中,参数value代表phone属性.因此,先把Integer类型的value转换为String类型,然后把它添加到JDBC Statement中.
定义了PhoneUserType类后,在Customer.hbm.xml中按如下方式映射Customer类的phone属性:
<property name="name" type="mypack.PhoneUserType">
<column name="phone" length="8"/>
</property>
PhoneUserType不仅仅可以用来映射phone属性,事实上,它能够把持久化类的任何一个Integer类型的属性映射到数据库中VARCHAR类型的字段.
分享到:
相关推荐
例如,使用Lombok库可以简化getter和setter的编写,而使用Hibernate Tools可以自动生成实体类和映射文件,这在处理大量自定义类型时非常有用。 总的来说,自定义数据类型是Hibernate的一个强大特性,它使我们能够...
在Java的Hibernate框架中,自定义类型是一种非常实用的功能,它允许开发者根据特定业务需求扩展Hibernate内置的数据类型。当我们发现Hibernate默认的数据类型无法满足我们存储数据的特殊要求时,例如需要处理复杂...
本例中,我们探讨的是如何结合Struts、Hibernate和自定义标签实现分页功能,这是一种常见的优化用户界面体验的技术,特别是对于数据量大的查询结果。 1. **分页原理** 分页的基本思想是将大量数据分成多个小部分,...
本文将深入探讨如何使用Hibernate实现领域对象的自定义字段,这涉及到对Hibernate核心概念的理解以及自定义类型的应用。 首先,我们需要了解Hibernate的核心概念。Hibernate主要通过配置文件(hibernate.cfg.xml)...
第四部分提到了Hibernate自定义类型对象以及如何序列化为字符串存储。自定义类型是Hibernate的一个高级特性,它允许开发者为复杂类型的数据自定义映射。这一部分可能介绍了如何创建自定义类型以及如何配置Hibernate...
1.4 Hibernate自定义类型 对象--->序列化为字符串 存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 1.5 Hibernate自定义类型 集合--->字符串 存储 . . . . . . . . . . . . . . ....
而在Java持久化框架Hibernate中,这些数据类型需要与数据库中的字段类型进行映射,以便正确地存储和检索数据。这篇博客主要探讨了Java数据类型如何与Hibernate的类型映射进行对应。 首先,Java的基本数据类型在...
这种方法的优点是代码更为简洁,不需要转换Clob开流,也不用编写Hibernate自定义类型。具体实现方式如下: 1. 建立包含Clob字段的数据库表,例如名为ITEMS_SAVECLOB的表。 2. 创建与数据库表对应的JavaBean,例如名...
4. **Hibernate自定义类型** Hibernate允许开发者自定义数据类型,将复杂对象如集合转化为字符串存储。这通常涉及到实现`UserType`接口,覆盖其中的方法如`sqlTypes()`、`returnedClass()`等。自定义类型可以用于...
4. **org.hibernate.type** 包:这里包含了各种Hibernate自定义类型,如日期时间类型、枚举类型等,它们将Java对象转换为数据库可识别的数据类型。 5. **org.hibernate.persister** 包:持久化相关的类,如`...
此外,Hibernate还支持自定义数据类型的映射,允许开发者根据需求扩展和定制。 在实际开发中,理解这些映射关系至关重要,因为它直接影响到数据的存储和查询效率,以及数据的一致性和完整性。例如,如果错误地将...
Hibernate Validation自定义注解校验的实现 Hibernate Validation自定义注解校验的实现是指在Hibernate Validation框架中,使用自定义的注解来实现特定的校验逻辑。在本文中,我们将通过示例代码,详细地介绍如何...
以上代码会返回一个Object数组列表,每个数组元素对应一条记录,需要手动将它们转换为自定义的对象。 总结起来,Hibernate的本地SQL查询功能为我们提供了一种灵活的方式来执行复杂的数据库操作,同时通过`addEntity...
##### 2.2 Hibernate自定义类型应用 为了在Hibernate中实现JSON数据的存取,文中引入了一个自定义的Hibernate类型`JsonType`。这个类型能够将Java中的对象转换成JSON字符串,便于存储到数据库中,同时也能将JSON...
在 Hibernate 框架中,使用自定义类型映射 Oracle 中的 LONG 类型字段是一种常见的解决方案。通过实现 UserType 接口,我们可以定制 LONG 类型字段的读写操作。在本例中,我们定义了一个名为 CustomLong 的类,该类...
为了实现审计日志,我们需要创建一个审计实体类,它包含如操作用户、操作时间、操作类型(增、删、改)、以及被操作的对象信息。然后,我们可以创建一个切面(Aspect),使用Spring的`@Before`、`@After`或`@Around`...
7. **扩展功能**:除了添加注释,自定义模板还可以实现其他高级功能,比如根据数据库字段类型生成特定的 Java 类型,或者为字段添加特定的注解(如 `@Column`、`@GeneratedValue`)。 8. **维护与更新**:当 ...
- **自定义Type**:创建自定义的Hibernate类型,覆盖默认的日期时间处理方式,以满足特定需求。 以上就是关于"解决Hibernate对于Date类型的数据返回结果中时分秒不对的问题"的详细分析和解决方案。在实际开发中,...
Hibernate,作为Java中广泛使用的对象关系映射(ORM)框架,提供了一种优雅的方式来映射枚举类型到数据库。本文将深入探讨Hibernate如何映射枚举类型,并给出实际应用示例。 ### Hibernate枚举映射方式 #### 1. `@...