攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型

Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性。
分为两种:内置映射类型和客户化映射类型。
一、内置映射类型
  1、Java基本类型的Hibernate映射类型

Java基础类型的Hibernate映射类型
Hibernate映射类型 Java类型 标准SQL类型 大小和取值范围
integer或者int int或者java.lang.Integer INTEGER  
long long BIGINT  
short short SMALLINT  
byte byte TINYINT  
float float FLOAT  
double double DOUBLE  
character char\String CHAR(1) 定长字符
string String VARCHAR 边长字符串
boolean boolean BIT  
yes_no boolean CHAR(1)  
true_false boolean CHAR(1)  


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

Java的时间日期类型的Hibernate映射类型
映射类型 Java类型 标准SQL类型 描述
date java.util.Date或者java.sql.Date DATE 代表日期
time java.Util.Date或者java.sql.Time TIME 代表时间
timestamp java.Util.Date或者java.sql.Timpstamp TIMESTAMP 代表时间和日期
calendar java.Util.Calendar TIMESTAMP 同上
calendar_date java.Util.Calendar DATE 代表日期


  3、Java大对象类型的Hibernate映射类型

Java大对象类型的Hibernate映射类型
映射类型 Java类型 标准SQL类型 MySQL类型 Oracle类型
binary byte[] VARBINARY(或者BLOB) BLOB BLOB
text java.lang.String CLOB TEXT CLOB
serializable 实现Serializable接口的类 VARBINARY(或者BLOB) BLOB BLOB
clob java.sql.Clob CLOB TEXT CLOB
blob java.sql.Blob BLOB BLOB BLOB


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

JDK自带的个别类的Hibernate映射类型
映射类型 Java类型 标准SQL类型
class java.lang.Class VARCHAR
locale java.util.Locale VARCHAR
timezone java.util.TimeZone VARCHAR
currency java.util.Currency VARCHAR


二、客户化映射类型
  通过实现org.hibernate.usertype.UserType接口即可,实现的是将一个Java类型如何映射为SQL类型。
  1、该接口的几个方法说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sqlTypes():设置该类型的字段对应的SQL类型。比如VARCHAR
returnClass():设置该类型的字段对应的Java类型。
isMutabel():判断对应的Java类型是否为可变类。
deepCopy(Object value):该方法用于生成对应属性的快照。对于可变类,必须返回参数的复制值。
equals(Object x, Object y):比较对应属性的当前值和它的快照是否相同。
hashCode(Object x):不做解释。
nullSaveGet(ResultSet resultSet,String[] names, Ojbect owner):
  当Hibernate从数据库加载对象时,调用该方法来取得该客户化类型的属性值。resultSet为JDBC的结果集,names为存放了表字段名的数组。在该方法内部实现从数据库字段到Java字段的转化。
nullSafeSet(PreparedStatement statement, Object value, int index):
  当Hibernate将对象持久化到数据库时,调用该方法把对应的属性值添加到SQL insert语句中。在该方法内部完成SQL语句的参数指定。
assemble(Serializable cached, Object owner):
  当Hibernate把二级缓存中的对象加载到Session缓存中时,调用该方法来获取对应属性的反序列化数据。如果参数cached为可变类型,则应该返回参数cached的快照(即调用deepCopy(cached))
disassemble(Object value):
  当Hibernate把Session缓存中的对象保存到二级缓存中时,调用该方法获取对应属性的序列化数据。如果参数value为可变类型,则应该返回参数cached的快照(即调用deepCopy(value))
replace(Object original, Object target, Object owner):
  当Session的merge()方法把一个游离对象A融合到持久化对象B时,会调用该方法来获得用于替代对象B对应属性的值。如果参数original为可变类型,则应该返回参数cached的快照(即调用deepCopy(original))

  2、配置文件使用

1
<property name="phone" type="xx.xx.MyType" column="PHONE"/>

  3、使用该方式替代Hibernate组件:方法就是将多个SQL字段在接口实现中封装为Address对象。

  4、实例代码

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;
  }
}  

三、操纵Blob和Clob类型数据
  在持久化类中,二进制大对象可以声明为byte[]或者java.sql.Blob;字符串大对象可以声明为java.lang.String或者java.sql.Clob类型。
  暂不解释。

 

声明:该文所有内容均来自《精通Hibernate:Java对象持久化技术详解》[孙卫琴 电子工业出版社] 一书。该文的目的仅仅作为学习笔记。若需要转载,请注明原书相关信息。

攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。