hibernate 自定义类型 范例

在经历自己的不良自定义类型解决方案后 这次就老老实实的实现了UserType接口

 

参考的网上的部分实例,发现很多同志都是从一个范例的演变过来的,都还是新手写的(虽然我也是新手哈),存在一些问题,

不多说了,看看我的实现吧

 

实现了一个Set<String>类型

package com.heypig.db.hibernate.myType;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class SetString implements UserType {
	/**
	 * 
	 * 在Hibernate中使用自定义类型需要实现org.hibernate.usertype.UserType接口,主要实现接口中的sqlTypes()、returnedClass()、isMutable()、equals()、deepCopy()、nullSafeGet()及nullSafeSet()方法。
	 * 
	 * int[] sqlTypes()方法要求返回自定义数据所在数据库字段的类型。类型通过java.sql.Types的类型常量来取得。
	 * 
	 * Class
	 * returnedClass()方法要求返回自定义数据在程序中的类型。如某自定义类型要将字符串转换成List,则这里返回List.class。
	 * 
	 * boolean isMutable()方法要求返回一个Boolean值,说明为本类型实例是否可变。注:不明白,默认为false。
	 * 
	 * Object deepCopy(Object
	 * obj)方法要求返回一个自定义类型的完全复制对象。说明:当nullSafeGet方法调用之后,我们获得自定义数据对象,在向用户返回自定义数据之前,deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户使用。
	 * 
	 * Object nullSafeGet(ResultSet rs, String[] names,Object
	 * owner)在从ResultSet中读取标记为自定义类型的数据时,会调用本方法。一般都是在本方法中将数据库中数据转换为自定义类型数据。注:names数组中存放着本自定义类型所代表的列的列名。(一个自定义类型可以在多个列使用,所以这里用的是数组
	 * 下面加以说明)
	 * 
	 * nullSafeSet(PreparedStatement ps, Object value, int
	 * index)在PreparedStatement执行之前会调用本方法。一般都是在本方法中将自定义类型数据转换成数据库中的数据类型。
	 * 
	 * nullSafeGet()和nullSafeSet()方法其实像一个拦截器,在执行java<->数据库的操作之前将操作拦截下来,并将自定义数据转换成所需类型。
	 * nullSafeGet()是先通过org.hibernate.Hibernate.XXXType.nullSafeGet()方法来取得数据,然后将数据转换成自定义类型并通过return将其返回。
	 * 
	 * nullSafeSet()是将自定义类型转换成数据库表中规定的类型,再通过org.hibernate.Hibernate.XXXType.nullSafeSet()方法将数据传入操作流。
	 * 
	 * 
	 * 
	 */

	private static final String SPILTTER = ",";
	private static final int[] TYPES = new int[] { Types.VARCHAR };

	public Object assemble(Serializable cached, Object owner)
			throws HibernateException {
		if (cached == null) {
			return null;
		} else {
			return deepCopy(owner);
		}
	}

	public Object deepCopy(Object value) throws HibernateException {

		Set<String> stringSet = (Set<String>) value;
		if (stringSet==null) {
			return null;
		}
		Set<String> stringSetCopy = new HashSet<String>();
		for (String string : stringSet) {
			String stringCopy = new String(string);
			stringSetCopy.add(stringCopy);
		}
		return stringSetCopy;
	}

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

	public boolean equals(Object x, Object y) throws HibernateException {
		Set<String> sx = (Set<String>) x;
		Set<String> sy = (Set<String>) y;
		if (sx==null) {
			return false;
		}
		if (sx.equals(sy)) {
			return true;
		}
		return false;
	}

	public int hashCode(Object x) throws HibernateException {

		return ((Set<String>) x).hashCode();
	}

	public boolean isMutable() {
		// TODO Auto-generated method stub
		return false;
	}

	public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
			throws HibernateException, SQLException {
		String stringFromDb = (String) Hibernate.STRING.nullSafeGet(rs,
				names[0]);

		String[] strings = stringFromDb.split(SPILTTER);
		Set<String> set = new HashSet<String>();
		for (String s : strings) {
			set.add(s);
		}
		return set;

	}

	public void nullSafeSet(PreparedStatement st, Object value, int index)
			throws HibernateException, SQLException {
		if (value != null) {
			Set<String> setString = (Set<String>) value;
			String stringToDb = "";
			for (String s : setString) {
				stringToDb += (s + SPILTTER);
			}
			Hibernate.STRING.nullSafeSet(st, stringToDb, index);
		} else {
			Hibernate.STRING.nullSafeSet(st, value, index);
		}

	}

	public Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		// TODO Auto-generated method stub
		return null;
	}

	public Class returnedClass() {
		return Set.class;
	}

	public int[] sqlTypes() {
		return TYPES;
	}

}

 

 

在xml映射里比普通类型的映射加一句type就ok了

<property name="newsCategorySet" type="com.heypig.db.hibernate.myType.SetString"></property>

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值