`
aasonwu
  • 浏览: 34572 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Hibernate 客户化映射类型--UserType

 
阅读更多


Hibernate 的客户化映射类型接口,允许用户以编程的方式创建自定义的映射类型,以实现把持久化类的任意类型的属性映射到数据库

以下例子可以把User类的Integer类型的phone属性映射到user表的varchar类型的phone字段

User.java

package com.wudasong.pojo;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

public class User implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 5767515928671889957L;
	
	private Long id;
	private String name;
	private String email;
	private Integer phone;
	private byte sex;
	private Date birthday;
	private String mark;
	private String password;
	private Timestamp registerTime;
	
	public User(){}
	
	public Long getId() {
		return id;
	}
	@SuppressWarnings("unused")
	private void setId(Long id) {
		this.id = id;
	}
	//此处省略User类的其他属性的getXXX()和setXXX()方法

}

自定义UserType类

package com.wudasong.pojo;

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{
	
	private static final int[] SQL_TYPES={Types.VARCHAR};
	
	@Override
	public int[] sqlTypes() {
		return SQL_TYPES;
	}

	@Override
	public Class<Integer> returnedClass() {
		return Integer.class;
	}

	@Override
	public boolean equals(Object x, Object y) throws HibernateException {
		if(x==y){
			return true;
		}else if(x==null||y==null){
			return false;
		}else {
			return x.equals(y);
		}
	}

	@Override
	public int hashCode(Object x) throws HibernateException {
		return x.hashCode();
	}

	@Override
	public Object deepCopy(Object value) throws HibernateException {
		return value;
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	@Override
	public Serializable disassemble(Object value) throws HibernateException {
		return (Serializable) value;
	}

	@Override
	public Object assemble(Serializable cached, Object owner)
			throws HibernateException {
		return cached;
	}

	@Override
	public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
			throws HibernateException, SQLException {
		if(resultSet.wasNull()){
			return null;
		}else{
			String phone=resultSet.getString(names[0]);
			return new Integer(phone);
		}
	}

	@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 original, Object target, Object owner)
			throws HibernateException {
		return original;
	}

} 

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wudasong.pojo" schema="wudasong_work">
	<class name="User" table="user" dynamic-insert="true" dynamic-update="true">
		<id name="id" column="id" type="long">
			<generator class="native" />
		</id>
		<property name="name" column="name" type="string" not-null="true" />
		<property name="email" column="email" type="string" not-null="true" />
                <!-- 自定义类型映射 -->
               <property name="phone" column="phone" type="com.wudasong.pojo.PhoneUserType" not-null="true" />
		<property name="sex" column="sex" type="byte" not-null="true" />
		<property name="birthday" column="birthday" type="date" />
		<property name="mark" column="mark" type="string" />
		<property name="password" column="password" type="string" not-null="true" />
		<property name="registerTime" column="registerTime" type="timestamp" insert="false" update="false"/>
	</class>
</hibernate-mapping>

说明:

PhoneUserType实现了org.hibernate.UserType接口的所有方法

  1. sqlTypes() 设置数据库中对应表的字段的类型,这里是varchar
  2. returnedClass() 设置数据库字段类型对应的Java类型,这里时Integer
  3. equals(Object x, Object y) hibernate会调用此方法比较当前对象是否和它的快照相同,参数x代表当前值,y代表有deepCopy()方法生成的属性快照值
  4. hashCode(Object x) 获得当前属性的hash码
  5. deepCopy(Object value) hibernate调用此方法生成快照的值,由于本例中Interger为不可变类,故直接返回value参数
  6. isMutable() 判断自定义属性类是否为可变类 ,此处Integer为不可变类,故返回false
  7. disassemble(Object value) 当hibernate把对象保存到第二缓存中时,调用此方法获得自定义属性的序列化数据
  8. assemble(Serializable cached, Object owner) 当hibernate从第二缓存中加载对象到session 时,调用此方法获得自定义属性(此例为:phone)的反序列化数据
  9. nullSafeGet(ResultSet resultSet, String[] names, Object owner) 当hibernate从数据库中加载对象时,调用此方法取得自定义属性的值
  10. nullSafeSet(PreparedStatement statement, Object value, int index) 当hibernate把对象持久化到数据库时,调用此方法把自定义属性的值添加到SQL 语句中
  11. replace(Object original, Object target, Object owner) 当session调用merge()方法把对象A融合到对象B时,调用此方法获得替代B对象的自定义属性的值

创建了PhoneUserType后,就可以以下面的方式实现自定义类型映射了

<property name="phone" column="phone" type="com.wudasong.pojo.PhoneUserType" not-null="true" />


附:

数据库user表scheme


CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `email` varchar(128) NOT NULL,
  `password` varchar(20) NOT NULL,
  `phone` varchar(20) NOT NULL,
  `sex` tinyint(4) NOT NULL DEFAULT '-1',
  `birthday` date DEFAULT NULL,
  `mark` varchar(200) DEFAULT NULL,
  `registerTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics