攻城狮在路上(壹) 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、该接口的几个方法说明:
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对象持久化技术详解》[孙卫琴 电子工业出版社] 一书。该文的目的仅仅作为学习笔记。若需要转载,请注明原书相关信息。)