Hibernate转换器
在org.hibernate.usertype.UserType
接口里面定义有如下一组操作方法:
方法 | 描述 |
---|---|
public Object assemble(Serializable cached,Object owner)throws HibernateException | 对象的反序列化操作,可以按照用户的需求将List集合转换为字符串 |
public Object deepCopy(Object value)throws HibernateException | 深度拷贝(全部拷贝) |
public Serializable disassemble(Object value)throws HibernateException | 序列化操作对象,例如将字符串拆分别为List集合 |
public boolean equals(Object x,Object y)throws HibernateException | 对象的比较操作(状态改变依靠比较完成) |
public int hashCode(Object x)throws HibernateException | 返回对象的哈希码(查找使用) |
public Object nullSafeGet(ResultSet re,String[] names,SessionImplementor session,Object owner)throws HibernateException,SQLException | 数据读取时所执行的操作方法 |
public Object nullSafeSet(PreparedStatement st,Object value,int index,SessionImplementor session)throws HibernateException,SQLException | 设置数据时所执行的操作方法 |
public Object replace(Object original,Object target,Object owner)throws HibernateException | 替换对象 |
public Class returnedClass() | 取得返回类型 |
public int sqlTypes() | 返回SQL类型 |
因为Hibernate本身的Session缓存不可关闭,所以有这么多的方法,目的是为了保证持久态可以正常操作。
实现List与String的转换
- 定义一个专门用于转换的处理类
package com.gub;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.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.Iterator;
import java.util.List;
//此时的工具类就可以实现List集合与String间的相互转换
public class ListStringUserType implements UserType {
@Override
public int[] sqlTypes() {
return new int[]{Types.VARBINARY};
}
@Override
public Class returnedClass() {
return List.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x.equals(y);//交由每个POJO类的equals()完成
}
@Override
public int hashCode(Object o) throws HibernateException {
return o.hashCode();
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor sessionImplementor, Object o) throws HibernateException, SQLException {
//取得数据之后,需要将字符串变为List集合
return this.disassemble(resultSet.getString(names[0]));
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor sessionImplementor) throws HibernateException, SQLException {
if(value==null){
st.setNull(index, Types.NULL);
}else{
st.setString(index, this.assemble(sessionImplementor,value).toString());
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if(value!=null){//先在有内容
List<String> oldList = (List<String>)value;
List<String> newList = new ArrayList<String>();
newList.addAll(oldList);//整体增加
return newList;
}
return null;
}
@Override
public boolean isMutable() {
return true;
}
/**
* 序列化操作,将字符串转换为List集合
* @param o
* @return
* @throws HibernateException
*/
@Override
public Serializable disassemble(Object value) throws HibernateException {
List<String> all = new ArrayList<String>();
String[] result = ((String)value).split("\\|");
for(int x=0;x<result.length;x++){
all.add(result[x]);
}
return (Serializable)all;
}
/**
* 反序列化操作,当用户进行进行数据保存的时候,需要将List集合变为String型数据
* @param cached
* @param owner
* @return
* @throws HibernateException
*/
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
StringBuffer buf = new StringBuffer();
List<String> all = (List<String>)owner;//以List集合形式进行数据接收
Iterator<String> iter = all.iterator();
while(iter.hasNext()){
buf.append(iter.next()).append("|");
}
buf.delete(buf.length()-1,buf.length());
return buf.toString();
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;//不替换
}
}
- 在POJO类需要转换的字段上使用Type注解
@Basic
@Column(name = "email")
@Type(type="com.gub.ListStringUserType")
public List<String> getEmail() {
return email;
}
- 编写转换测试
package test;
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.User;
public class ConvertTest {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("没名字");
user.getEmail().add("NicholasGUB@163.com");
user.getEmail().add("2337878268@qq.com");
user.getEmail().add("2286366604@qq.com");
HibernateSessionFactory.getSession().save(user);
HibernateSessionFactory.getSession().beginTransaction().commit();
HibernateSessionFactory.closeSession();
}
}
此时发现数据保存成功(List集合成功变为指定格式的字符串)
观察读取操作
package test;
import com.gub.dbc.HibernateSessionFactory;
import com.gub.vo.User;
public class ConvertTest {
public static void main(String[] args) {
User user = (User)HibernateSessionFactory.getSession().get(User.class,1);
System.out.println(user);
HibernateSessionFactory.closeSession();
}
}
此时发现数据读取成功
实现JSON数据转换
- 修改转换的处理类的assemble与disassemble方法
@Override
public Serializable disassemble(Object value) throws HibernateException {
List<String> all = new ArrayList<String>();
JSONObject obj = JSONObject.fromObject(value);
JSONArray array = obj.getJSONArray("emails");
for(Object x:array){
all.add(x.toString());
}
return (Serializable)all;
}
/**
* 反序列化操作,当用户进行进行数据保存的时候,需要将List集合变为String型数据
* @param cached
* @param owner
* @return
* @throws HibernateException
*/
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
JSONObject obj = new JSONObject();
JSONArray array = new JSONArray();
List<String> all = (List<String>)owner;//以List集合形式进行数据接收
Iterator<String> iter = all.iterator();
while(iter.hasNext()){
array.add(iter.next());
}
obj.put("emails",array);
return obj.toString();
}
- 修改POJO类上的转换器
@Basic
@Column(name = "email")
@Type(type="com.gub.ListANDJSONUserType")
public List<String> getEmail() {
return email;
}
这样一个List-JSON转换器就做好了,直接使用以上的测试程序,发现结果一致。