Hibernate存取JSON数据

package com.keepithttps.hibernate.type;

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

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Objects;

/**
* Hibernate {@link UserType} implementation to handle JSON objects
*
* @see https
*      ://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/usertype/
*      UserType.html
*/
public class JSONUserType implements UserType, ParameterizedType, Serializable {
  
  private static final long serialVersionUID = 1L;
  
  private static final ObjectMapper MAPPER = new ObjectMapper();
  
  private static final String CLASS_TYPE = "classType";
  private static final String TYPE = "type";
  
  private static final int[] SQL_TYPES = new int[] { Types.LONGVARCHAR, Types.CLOB, Types.BLOB };
  
  private Class<?> classType;
  private int sqlType = Types.LONGVARCHAR; // before any guessing
  
  @Override
  public void setParameterValues(Properties params) {
    String classTypeName = params.getProperty(CLASS_TYPE);
    try {
      this.classType = ReflectHelper.classForName(classTypeName, this.getClass());
    } catch (ClassNotFoundException cnfe) {
      throw new HibernateException("classType not found", cnfe);
    }
    String type = params.getProperty(TYPE);
    if (type != null) {
      this.sqlType = Integer.decode(type).intValue();
    }
    
  }
  
  @Override
  public Object assemble(Serializable cached, Object owner) throws HibernateException {
    return this.deepCopy(cached);
  }
  
  @Override
  public Object deepCopy(Object value) throws HibernateException {
    Object copy = null;
    if (value != null) {
      
      try {
        return MAPPER.readValue(MAPPER.writeValueAsString(value), this.classType);
      } catch (IOException e) {
        throw new HibernateException("unable to deep copy object", e);
      }
    }
    return copy;
  }
  
  @Override
  public Serializable disassemble(Object value) throws HibernateException {
    try {
      return MAPPER.writeValueAsString(value);
    } catch (JsonProcessingException e) {
      throw new HibernateException("unable to disassemble object", e);
    }
  }
  
  @Override
  public boolean equals(Object x, Object y) throws HibernateException {
    return Objects.equal(x, y);
  }
  
  @Override
  public int hashCode(Object x) throws HibernateException {
    return Objects.hashCode(x);
  }
  
  @Override
  public boolean isMutable() {
    return true;
  }
  
  @Override
  public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException,
  SQLException {
    Object obj = null;
    if (!rs.wasNull()) {
      if (this.sqlType == Types.CLOB || this.sqlType == Types.BLOB) {
        byte[] bytes = rs.getBytes(names[0]);
        if (bytes != null) {
          try {
            obj = MAPPER.readValue(bytes, this.classType);
          } catch (IOException e) {
            throw new HibernateException("unable to read object from result set", e);
          }
        }
      } else {
        try {
          obj = MAPPER.readValue(rs.getString(names[0]), this.classType);
        } catch (IOException e) {
          throw new HibernateException("unable to read object from result set", e);
        }
      }
    }
    return obj;
  }
  
  @Override
  public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException,
  SQLException {
    if (value == null) {
      st.setNull(index, this.sqlType);
    } else {
      
      if (this.sqlType == Types.CLOB || this.sqlType == Types.BLOB) {
        try {
          st.setBytes(index, MAPPER.writeValueAsBytes(value));
        } catch (JsonProcessingException e) {
          throw new HibernateException("unable to set object to result set", e);
        }
      } else {
        try {
          st.setString(index, MAPPER.writeValueAsString(value));
        } catch (JsonProcessingException e) {
          throw new HibernateException("unable to set object to result set", e);
        }
      }
    }
  }
  
  @Override
  public Object replace(Object original, Object target, Object owner) throws HibernateException {
    return this.deepCopy(original);
  }
  
  @Override
  public Class<?> returnedClass() {
    return this.classType;
  }
  
  @Override
  public int[] sqlTypes() {
    return SQL_TYPES;
  }
}



转载于:https://my.oschina.net/ousinka/blog/368863

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值