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

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

Java基础类型的Hibernate映射类型
Hibernate映射类型Java类型标准SQL类型大小和取值范围
integer或者intint或者java.lang.IntegerINTEGER 
longlongBIGINT 
shortshortSMALLINT 
bytebyteTINYINT 
floatfloatFLOAT 
doubledoubleDOUBLE 
characterchar\StringCHAR(1)定长字符
stringStringVARCHAR边长字符串
booleanbooleanBIT 
yes_nobooleanCHAR(1) 
true_falsebooleanCHAR(1) 


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

Java的时间日期类型的Hibernate映射类型
映射类型Java类型标准SQL类型描述
datejava.util.Date或者java.sql.DateDATE代表日期
timejava.Util.Date或者java.sql.TimeTIME代表时间
timestampjava.Util.Date或者java.sql.TimpstampTIMESTAMP代表时间和日期
calendarjava.Util.CalendarTIMESTAMP同上
calendar_datejava.Util.CalendarDATE代表日期


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

Java大对象类型的Hibernate映射类型
映射类型Java类型标准SQL类型MySQL类型Oracle类型
binarybyte[]VARBINARY(或者BLOB)BLOBBLOB
textjava.lang.StringCLOBTEXTCLOB
serializable实现Serializable接口的类VARBINARY(或者BLOB)BLOBBLOB
clobjava.sql.ClobCLOBTEXTCLOB
blobjava.sql.BlobBLOBBLOBBLOB


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

JDK自带的个别类的Hibernate映射类型
映射类型Java类型标准SQL类型
classjava.lang.ClassVARCHAR
localejava.util.LocaleVARCHAR
timezonejava.util.TimeZoneVARCHAR
currencyjava.util.CurrencyVARCHAR


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

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、配置文件使用

<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对象持久化技术详解》[孙卫琴 电子工业出版社] 一书。该文的目的仅仅作为学习笔记。若需要转载,请注明原书相关信息。

转载于:https://www.cnblogs.com/tq03/p/3768782.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值