`
conkeyn
  • 浏览: 1504456 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

Hibernate annotation 自定义类型 userType

 
阅读更多

第一步:添加自定义类:

package com.a.entity;

import java.io.Serializable;

public class ConfigEntry implements Serializable {
	private static final long serialVersionUID = 6796578004411833529L;

	private String key;
	private String value;
	private Integer type;
	
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public Integer getType() {
		return type;
	}
	public void setType(Integer type) {
		this.type = type;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((key == null) ? 0 : key.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ConfigEntry other = (ConfigEntry) obj;
		if (key == null) {
			if (other.key != null)
				return false;
		} else if (!key.equals(other.key))
			return false;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		if (value == null) {
			if (other.value != null)
				return false;
		} else if (!value.equals(other.value))
			return false;
		return true;
	}

}

 

第二步:添加Hibernate UserType的实现类:

package com.aspire.usertype;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import net.sf.json.JSONArray;

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

public class ListObjectType implements UserType, ParameterizedType {
	private static final int[] TYPES = new int[] { Types.CLOB };
	private static final String paramName = "clazzName";
	private Properties parameters;

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

	@Override
	public Object deepCopy(Object object) throws HibernateException {
		if (object == null)
			return null;
		if (!(object instanceof java.util.List))
			throw new UnsupportedOperationException("can't convert " + object.getClass());
		List sourceSet = (List) object;
		List targetSet = new ArrayList();
		if (sourceSet != null) {
			targetSet.addAll(sourceSet);
		}
		return targetSet;
	}

	@Override
	public Serializable disassemble(Object object) throws HibernateException {
		if (!(object instanceof java.util.List))
			throw new UnsupportedOperationException("can't convert " + object.getClass());
		return (Serializable) deepCopy(object);
	}

	@Override
	public boolean equals(Object one, Object other) throws HibernateException {
		if (one == other) {// 如果两个对象的指针是指向同一位置。
			return true;
		}
		if (!(one instanceof java.util.List))
			throw new UnsupportedOperationException("can't convert " + one.getClass());
		if (!(other instanceof java.util.List))
			throw new UnsupportedOperationException("can't convert " + other.getClass());
		if (one != null && other != null) {
			List set0 = (List) one;
			List set1 = (List) other;
			if (set0.size() != set1.size()) {// 如果列表的长度不相等
				return false;
			}
			Object[] s0 = set0.toArray();
			Object[] s1 = set1.toArray();
			if (s0.length != s1.length) {// 如果列表的长度不相等
				return false;
			}
			for (int i = 0; i < s0.length; i++) {
				Object id0 = s0[i];
				Object id1 = s1[i];
				if (!id0.equals(id1)) {// 如果在列表中相同位置上的对象不相等
					return false;
				}
			}
			return true;
		}
		return false;
	}

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

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

	@Override
	public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
		String value = rs.getString(names[0]);
		List resultList = null;
		if (value != null) {
			try {
				String clazzName = parameters.getProperty(paramName);
				resultList = parse(value, Class.forName(clazzName));
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		} else {
			resultList = new ArrayList();
		}
		return resultList;
	}

	/**
	 * 解析JSON字符成对象
	 * 
	 * @param value
	 * @return
	 */
	private List parse(String value, Class clazz) {
		List resultList = null;
		if (value != null) {
			JSONArray jsonArray = JSONArray.fromObject(value);
			resultList = jsonArray.toList(jsonArray, clazz);
		} else {
			resultList = new ArrayList();
		}
		return resultList;
	}

	/**
	 * 格式化对象成Json字符串
	 * 
	 * @param value
	 * @return
	 * @throws ClassNotFoundException
	 */
	private String format(List value) {
		String result = null;
		if (value != null) {
			JSONArray jsonArray = JSONArray.fromObject(value);
			result = jsonArray.toString();
		}
		return result;
	}

	@Override
	public void nullSafeSet(PreparedStatement stmt, Object value, int index) throws HibernateException, SQLException {
		if (value == null) {
			stmt.setNull(index, Types.CLOB);
			return;
		}
		if (!(value instanceof java.util.List))
			throw new UnsupportedOperationException("can't convert " + value.getClass());
		stmt.setString(index, format((java.util.List) value));
	}

	@Override
	public Object replace(Object original, @SuppressWarnings("unused") Object target, @SuppressWarnings("unused") Object owner)
			throws HibernateException {
		return original;
	}

	@Override
	public Class returnedClass() {
		return List.class;
	}

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

	@Override
	public void setParameterValues(Properties parameters) {
		this.parameters = parameters;

	}

}

 第三步:添加组合关键字字,

package com.a.entity;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Embeddable
public class ClientAppCfgId implements Serializable {

	private static final long serialVersionUID = 2291408665473574896L;

	@ManyToOne(targetEntity = ClientApp.class, cascade = { CascadeType.ALL }, optional = false)
	@JoinColumn(name = "app_id")
	@OnDelete(action = OnDeleteAction.CASCADE)
	private ClientApp app;
	
	@ManyToOne(targetEntity = Area.class, cascade = { CascadeType.ALL }, optional = false)
	@JoinColumn(name = "area_id")
	@OnDelete(action = OnDeleteAction.CASCADE)
	private Area area;

	public ClientApp getApp() {
		return app;
	}

	public void setApp(ClientApp app) {
		this.app = app;
	}

	public Area getArea() {
		return area;
	}

	public void setArea(Area area) {
		this.area = area;
	}

}

 

 

第四步:配置属性:

package com.a.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

/** 客户端配置 */
@TypeDefs({
		@TypeDef(name = "listObjectType", typeClass = com.a.usertype.ListObjectType.class, parameters = { @Parameter(name = "clazzName", value = "com.a.entity.ConfigEntry") }) })
@Entity
@Table(name = "t_client_app_cfg")
public class ClientAppCfg implements Serializable {

	private static final long serialVersionUID = -8929122435053630855L;

	@Id
	private ClientAppCfgId id;


	/***/
	@Type(type = "listObjectType")
	@Column(name = "config_params", columnDefinition = " clob default null")
	private List<ConfigEntry> configParams;

	public ClientAppCfgId getId() {
		return id;
	}

	public void setId(ClientAppCfgId id) {
		this.id = id;
	}


	public List<ConfigEntry> getConfigParams() {
		return configParams;
	}

	public void setConfigParams(List<ConfigEntry> configParams) {
		this.configParams = configParams;
	}

}

 第五:运行应用,将自动创建表(以下是表结构创建示例):

create table T_CLIENT_APP_CFG
(
  bg_type       NUMBER(10),
  bg_value      VARCHAR2(255 CHAR),
  help_url      VARCHAR2(500 CHAR),
  show_style    NUMBER(10),
  ver           NUMBER(10),
  app_id        NUMBER(19) not null,
  area_id       NUMBER(19) not null,
  config_params CLOB,
  primary key (APP_ID, AREA_ID)
)

 第六:插入数据:

INSERT INTO T_CLIENT_APP_CFG(APP_ID, AREA_ID, CONFIG_PARAMS) 
VALUES (10000, 1001, '[{"key":"a","type":0,"value":"a1"},{"key":"b","type":1,"value":"b1"},
{"key":"c","type":3,"value":"c1"},{"key":"d","type":4,"value":"d1"},
{"key":"e","type":5,"value":"e1"},{"key":"f","type":6,"value":"f1"},
{"key":"g","type":7,"value":"g1"},{"key":"h","type":8,"value":"h1"}]');

 第七:可以使用java代码试试。

 

第八:关于第四步的配置方法还有另外一种,可以参考以下示例:

package com.a.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;

/** 客户端配置 */
@Entity
@Table(name = "t_client_app_cfg")
public class ClientAppCfg implements Serializable {

	private static final long serialVersionUID = -8929122435053630855L;

	@Id
	private ClientAppCfgId id;


	/***/
	@Type(type= "com.a.usertype.ListObjectType", parameters = { @Parameter(name = "clazzName", value = "com.a.entity.ConfigEntry") })
	@Column(name = "config_params", columnDefinition = " clob default null")
	private List<ConfigEntry> configParams;

	public ClientAppCfgId getId() {
		return id;
	}

	public void setId(ClientAppCfgId id) {
		this.id = id;
	}

	public List<ConfigEntry> getConfigParams() {
		return configParams;
	}

	public void setConfigParams(List<ConfigEntry> configParams) {
		this.configParams = configParams;
	}

}

 

分享到:
评论
2 楼 mu_xiaoxia 2014-04-10  
楼主@Type是啥意思
1 楼 nieruiqiao 2013-05-02  
  好久没有更新了啊

相关推荐

Global site tag (gtag.js) - Google Analytics