Hibernate的映射类型分为两种,内置映射类型和客户化映射类型。
内置映射类型:负责把一些常见的java类型映射到相应的SQL类型
客户化映射类型:Hibernate允许用户实现UserType或CompositeUserType接口,来灵活定制客户化映射类型。客户化映射类型能够把用户定义的Java类型映射到数据库表的相应字段。
1、Hibernate内置的映射类型
1.1 Java基本的类型的Hibernate映射
int或integer——INTEGER
long——BIGINT
short——SMALLINT
byte——TINYINT
float——FLOAT
double——DOUBLE
big_decimal——NUMBERIC
character——CHAR
string——VARCHAR
boolean——BIT
1.2 Java时间和日期类型的Hibernate映射类型
date——DATE
time——TIME
timestamp——TIMESTAMP
calender—— TIMESTAMP
calender_date——DATE
1.2 Java大对象类型的Hibernate映射类型
binary——BLOB(Mysql)、BLOB(Oracle)
text——TEXT(Mysql)、CLOB(Oracle)
serializable——TEXT(Mysql)、CLOB(Oracle)
blob——BLOB(Mysql)、BLOB(Oracle)
假定Customer类的description属性为Java.sql.Clob类型,在Oracle数据库中的CUSTOMERS表的DESCRIPTION字段为CLOB类型,Customer.hbm.xml如下:
在应用程序中通过Hibernate来保存java.sql.Clob或java.sql.Blob实例时,必须包含两个步骤:
1.在数据库事务中先保存一个空的Clob或者Blob实例
2.接着锁定这条记录,更新步骤1中保存的Blob或Clob实例,把二进制数据或文本数据写到Blob或Clob实例中。例如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
customer = new Customer();
customer.setDescription(Hibernate.createClob(” “));
session.save(customer);
// 锁定这条记录
session.refresh(customer,LockMode.UPGRADE);
oracle.sql.CLOB clob = (oracle.sql.CLOB)customer.getDescription();
java.io.write pw = clob.getCharacterOutputStream();
pw.write(longText);
pw.close;
tx.commit();
session.close();
2、客户化映射类型
Hibernate 的客户化映射类型接口,允许用户以编程的方式创建自定义的映射类型,以实现把持久化类的任意类型的属性映射到数据库
例如PhoneUserType实现了net.sf.hibernate.UserType接口,它能够把Customer类的integer类型的phone属性映射到CUSTOMER表的varchar类型的PHONE字段。
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class PhoneUserType implements UserType {
// 设置Customer表的phone字段的sql类型,他是varchar类型
private static final int[] SQL_TYPES = {Types.VARCHAR};
@Override
public int[] sqlTypes() {
return SQL_TYPES;
}
// 设置Customer类phone属性的java类型,他是integer类型
@Override
public Class returnedClass() {
return Integer.class;
}
@Override
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
return null;
}
// Hibernate调用deepCopy(Object value)方法来生成phone属性快照,value代表Integer类型的phone属性
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if(x == y) return true;
if(x == null || y == null) return false;
return x.equals(y);
}
@Override
public int hashCode(Object arg0) throws HibernateException {
return 0;
}
// 通过此方法判断Integer类是否是可变类,Hibernate在处理不可变类的时候会采取一些优化措施
@Override
public boolean isMutable() {
return false;
}
// 当Hibernate从数据库中加载Customer对象时,调用此方法来取得phone属性值
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {
if(resultSet.wasNull()) return null;
String phone = resultSet.getString(names[0]);
return new Integer(phone);
}
// 当Hibernate把Customer对象持久化到数据库中调用此方法把phone属性添加到insert sql语句中
@Override
public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {
if(value == null){
statement.setNull(index, Types.VARCHAR);
}
else{
String phone = ((Integer)value).toString();
statement.setString(index, phone);
}
}
@Override
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return null;
}
}
定义了PhoneUserType类后,在Customer.hbm.xml文件中按如下映射配置: