第一步:添加自定义类:
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;
}
}