Hibernate的映射类型

本文介绍了Hibernate的映射类型,包括内置的基本类型、日期时间、大对象和JDK自带类的映射,以及如何实现客户化映射类型,特别强调了客户化映射在处理不可变类的优势和映射过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 概述

Hibernate映射类型分为两种:内置映射类型和客户化映射类型。

内置类型负责把一些常见的java类型映射到相应的SQL类型。String到varchar的映射如图1所示:

图1-1  hibernate内置类型string完成String到varchar的映射

客户化映射类型可以把用户定义的java类型映射到数据表的相应字段。通过实现Hibernate的UserType接口。

2. 内置映射类型

(此处内容仅为以后设计做参考)

2.1 基本类型的Hibernate映射类型

表2-1基本类型的Hibernate映射类型


 

2.2 java日期和时间类型的Hibernate映射

表2-2 Java日期和时间类型的Hibernate映射类型


2.3 Java大对象类型的Hibernate映射

表2-3 Java大对象类型的Hibernate映射



2.4 JDK自带的个别Java类的Hibernate映射类型

表2-4JDK自带的个别Java类的Hibernate映射类型


3. 客户化映射类型

Hibernate提供了客户化的映射类型接口,允许用户以编程的方式实现把持久化类的任意类型的属性映射到数据库中。

如下面的AddressUserType实现了将Address型的属性映射到数据库。

package mypack;
import org.hibernate.*;
import org.hibernate.usertype.*;
import java.sql.*;
import java.io.Serializable;

public class AddressUserType implements UserType {

  private static final int[] SQL_TYPES = {Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR};

  public int[] sqlTypes() { return SQL_TYPES; }

  public Class returnedClass() { return Address.class; }

  public boolean isMutable() { return false; }

  public Object deepCopy(Object value) {
    return value; // Address is immutable
  }

  public boolean equals(Object x, Object y) {
    if (x == y) return true;
    if (x == null || y == null) return false;
    return x.equals(y);
  }

  public int hashCode(Object x){
    return x.hashCode();
  }
  
  public Object nullSafeGet(ResultSet resultSet,String[] names, Object owner)
  throws HibernateException, SQLException {

    String province = resultSet.getString(names[0]);
    String city = resultSet.getString(names[1]);
    String street = resultSet.getString(names[2]);
    String zipcode = resultSet.getString(names[3]);

    if(province ==null  && city==null  && street==null  && zipcode==null)
      return null;

    return new Address(province,city,street,zipcode);
  }

  public void nullSafeSet(PreparedStatement statement,Object value,int index)
  throws HibernateException, SQLException {

    if (value == null) {
      statement.setNull(index, Types.VARCHAR);
      statement.setNull(index+1, Types.VARCHAR);
      statement.setNull(index+2, Types.VARCHAR);
      statement.setNull(index+3, Types.VARCHAR);
    } else {
      Address address=(Address)value;
      statement.setString(index, address.getProvince());
      statement.setString(index+1, address.getCity());
      statement.setString(index+2, address.getStreet());
      statement.setString(index+3, address.getZipcode());
    }
  }

  public Object assemble(Serializable cached, Object owner){
    return cached;
  }

  public Serializable disassemble(Object value) {
    return (Serializable)value;
  }
  
  public Object replace(Object original,Object target,Object owner){
    return original;
  }
}
有兴趣的读者可以研究一下其中的实现过程。

4. 用客户化映射类型取代Hibernate组件

4.1 区分可变类和不可变类

可变类:创建了实例后,可以修改它的属性;

不可变类:当创建了这种类的实例后,就不许修改它的属性。其设计模式:

  • 属性定义为private final。
  • 不对外公开setXXX()方法(即不编写此方法)。
  • 只对外公开getXXX()方法。
  • 允许构造方法中设置所有的属性。
  • 覆盖Object类的equals()和hashCode()方法。

Java中的基本类型的包装类都是不可变类,所以这里的Address类也必须是不可变类。(数据类型当然不可更改)

4.2 实现映射

  • 定义一个Hibernate映射类型AddressUserType(如上面所示),它把Address类型的属性映射到数据库。
  • 修改Monkey.hfg.xml,使用客户化映射类型AddressUserType映射Monkey类中的Address类型属性到数据库。

映射homeAddress的代码:

<property name="homeAddress" type="mypack.AddressUserType" >
        <column name="HOME_PROVINCE" />
        <column name="HOME_CITY" />
        <column name="HOME_STREET"/>
        <column name="HOME_ZIPCODE" />
    </property>

4.3 比较Hibernate组件映射和客户化映射类型映射

Hibernate组件和客户化映射类型那个都是值类型。

  • Hibernate组件采用的是xml配置方式,具有较好的可维护性;
  • 客户化映射类型采用的是编程方式,能够完成更加复杂灵活的映射。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值