Hibernate 映射类型

  • Post author:
  • Post category:其他




Hibernate


有两种映射类型,一种是内置映射类型,它把一些常见的


JAVA


类型映射到相应的


SQL


类型,另一种是客户化映射类型,它把用户定义的


JAVA


类型映射到数据库表的相应字段



Hibernate


的内置映射类型





1




JAVA


基本类型


(


包括它们的包装类


)





Hibernate


映射类型


Hibernate


Java


类型


标准


SQL


类型


大小和取值范围


integer/int


int/java.lang.Integer


integer


4


字节,


-2^31~2^31-1


long


long/java.lang.Long


bigint


8


字节


, -2^63~2^63-1


short


short/java.lang.Short


smallint


2


字节


, -2^15~2^15-1


byte


byte/java.lang.Byte


tinyint


1


字节


, -128~127


flat


float/java.lang.Float


float


4


字节


,





单精度浮点数


double


double/java.lang.Double


double


8


字节


,


双精度浮点数


big_decimal


java.math.BigDecimal


numeric


用法:


numeric(8,2)


character


char/…Character/…String


char(1)


定长字符


string


java.lang.String


varchar


变长字符串


boolean


boolean/java.lang.Boolean


bit


布尔类型


yes_no


boolean/java.lang.Boolean


char(1)(‘Y’/’N’)


布尔类型


true_false


boolean/java.lang.Boolean


char(1)(‘T’/’F’)


布尔类型







2




JAVA


时间和日期类型的


Hibernate




映射类



映射类型


java


类型


标准


SQL


类型


描述


date


java.util.Date/java.sql.Date


date


日期,形式


:yyyy-mm-dd


time


java.util.Date/java.sql.Time


time


时间,形式


:hh:mm:ss


timestamp


…Date/java.sql.Timestamp


timestamp


形式


:yyyymmddhhmmss


calendar


java.util.Calendar


timestamp


时间和日期,形式同上


calendar_date


java.util.Calendar


date


日期


,


形式


:yyyy-mm-dd


在标准


SQL


中,


DATE


表示日期


(2005-01-09)





TIME


表示时间


(11:46:54)





TIMESTAMP


表示时间戳,包含日期和时间信息


(20050109114654),


如果没有显式插入,由系统自动添加当前系统时间





3


Java


大对象类型的


Hibernate


映射类型


映射类型


Java


类型


标准


SQL


类型


描述


binary


byte[]


varbinary/blob


存放二进制数


text


java.lang.String


clob


字符串大对象


serializable


实现


java.io.Serializable


接口的类


varbinary/blob




clob


java.sql.Clob


clob


字符串大对象


bolb


java.sql.Blob


blob


二进制大对象


MySQL


不支持标准


SQL





CLOB


类型。


通过


Hibernate


来保存


java.sql.Clob





java.sql.Blob


实例时,发须包含两个步骤:



(1)








在一个数据库事务中先保存一个空的


Blob





Clob


实例



(2)








锁定记录,更新上一步保存的


Bolb





Clob


实例,把二进制数或长文本写进去,如:

Customer customer=new Customer();
customer.setDescription(Hibernate.createClob(“”));//保存一个空的Clob实例
session.save(customer);
session.flush();
session.refresh(customer,LockMode.UPGRADE);//锁定记录
oracle.sql.CLOB clob=(oracle.sql.CLOB)customer.getDescription();
java.io.Writer pw=clob.getCharacterOutputStream();
pw.write(longText);//lognText变量表示长度超过255的字符串
pw.close();
tx.commit();
session.close();


以上不用


java.sql.Blob





java.sql.Clob


处理


JAVA


大对有以下两个原因:



(1)








Blob





Clob


实例只有在一个数据库事务中才有效



(2)








有些数据库的


JDBC


驱动程序不支持


java.sql.Blob





java.sq.Clob


。如果在


Java


应用中处理图片或长文件的二进制数用


byte[]





java.sql.Blob


方便


;


如果处理长度超过


255


的字符串


java.lang.String





java.sql.Clob


更方法









JDK


自带的个别


JAVA


类的


Hibernate


映射类型


映射类型


Java


类型


标准


SQL


类型


class


java.lang.Class


VARCHAR


locale(


现场


)


java.util.Locale


VARCHAR


timezone(


地区


)


java.util.TimeZone


VARCHAR


currency(


流通


)


java.utilCurrency


VARCHAR



使用


Hibernate


内置映射类型


有的数据库并不支持所有的标准


SQL


类型,如


Oracle


开发了变长字符串


varchar2


来代替


varchar.


怎样使


Hibernate


可以使用标准的


SQL


类型来生成


DML


(Date Manipulation Language)?(


如我在


<column>





sql-type


中用标准的


SQL


类型,要它生成底层数据库支持的类型


.Manipulation:


处理


.)


解决方案


:


Java


应用通过


Hibernate


访问数据库,而


Hibernate


又通过


JDBC


驱动程序访数据库,


JDBC


对底层数据库


SQL


类型进行封装,向上提供标准的


SQL


类型接口,这样


Hibernate


就可以根据底层数据库使用的


SQL


方言,把标准


SQL


类型翻译成底成数据库类型。如:


<property name=”email” type=”string” length=”50”>


如果连接的是


Oracle





hbm2ddl


生成的脚本为


…carchar2(50).





string





>


标准


SQL varchar





>Oracle varchar2




一个java类型对应多个Hibernate映射类型的场合。例如,如果持久化类的属性为java.util.Date类型,对应的Hibernate映射类型可以是date,time或timestamp。此时必须根据对应的数据库表的字段的SQL类型,来确定Hibernate映射类型。如果字段为Date类型,则hibernate映射为datge,如果为TIME则为time,如果为TIMESTAMP则为timestamp。





客户化映射类型


Hiberante


提供了客户化映射类型接口


(net.sf.hibernate.UserType





CompositeUserType)


,允许用户创建自定义的映射类型,把持久化类的任意类型的属性映射到数据库中




Address.java




package mypack;  
import java.io.Serializable;  
 
public class Address implements Serializable {  
    private final String province;  
    private final String city;  
    private final String street;  
    private final String zipcode;  
 
    public Address(String province, String 
city, String street, String zipcode){  
        this.street = street;  
        this.city = city;  
        this.province = province;  
        this.zipcode = zipcode;  
    }  
    public String getProvince() {  
        return this.province;  
    }  
      
    public String getCity() {  
        return this.city;  
    }  
    public String getStreet() {  
        return this.street;  
    }  
    public String getZipcode() {  
        return this.zipcode;  
    }  
    public boolean equals(Object o){  
      if (this == o) return true;  
      if (!(o instanceof Address)) return false;  
         final Address address = (Address) o;  
         if(!province.equals(address.province)) return false;  
         if(!city.equals(address.city)) return false;  
         if(!street.equals(address.street)) return false;  
         if(!zipcode.equals(address.zipcode)) return false;  
         return true;  
    }  
    public int hashCode(){  
       int result;  
       result= (province==null?0:province.hashCode());  
       result = 29 * result + (city==null?0:city.hashCode());  
       result = 29 * result + (street==null?0:street.hashCode());  
       result = 29 * result + (zipcode==null?0:zipcode.hashCode());  
       return result;  
    }  
} 



AddressUserType类的源程序,它实现了UserType接口


package mypack;  
import org.hibernate.*;  
import org.hibernate.usertype.*;  
import java.sql.*;  
 
public class AddressUserType implements UserType {  
    
  /** 设置和Address类的四个属性province、city、street和zipcode对应  
  的字段的SQL类型,它们均为VARCHAR类型 */ 
  private static final int[] SQL_TYPES =   
  {Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR};  
    
  public int[] sqlTypes() { return SQL_TYPES; }  
    
  /** 设置AddressUserType所映射的Java类:Address类 */ 
  public Class returnedClass() { return Address.class; }  
    
  /** 指明Address类是不可变类 */ 
  public boolean isMutable() { return false; }  
    
  /** 返回Address对象的快照,由于Address类是不可变类,  
  因此直接将参数代表的Address对象返回 */ 
  public Object deepCopy(Object value) {  
    return value;   
  }  
    
  /** 比较一个Address对象是否和它的快照相同 */ 
  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();  
  }  
 
  /** 从JDBC ResultSet中读取province、city、street和zipcode,  
  然后构造一个Address对象*/ 
  public Object nullSafeGet(ResultSet resultSet, 
String[] names, Object owner)  
                       throws HibernateException, SQLException {  
    if (resultSet.wasNull()) return null;  
    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);  
  }  
    
  /** 把Address对象的属性添加到JDBC PreparedStatement中 */ 
  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;  
  }  
} 



创建了以上的AddressUserType后,就可以按以下方式映射Customer类的homeAddress和comAddress属性


<property name="homeAddress" type="mypack.AddressUserType" >  
        <column name="HOME_STREET" length="15" />  
        <column name="HOME_CITY" length="15" />  
        <column name="HOME_PROVINCE" length="15" />  
        <column name="HOME_ZIPCODE" length="6" />  
</property>  
 
<property name="comAddress" type="mypack.AddressUserType" >  
        <column name="COM_STREET" length="15" />  
        <column name="COM_CITY" length="15" />  
        <column name="COM_PROVINCE" length="15" />  
        <column name="COM_ZIPCODE" length="6" />  
</property> 



版权声明:本文为jazywoo123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。