PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/common/src/main/java/com/sishuok/es/common/repository/hibernate/type/HashMapToStringUserType.java

https://gitlab.com/0072016/es
Java | 187 lines | 113 code | 24 blank | 50 comment | 15 complexity | 93040f9b31f4cac6aac31ce0c10e2307 MD5 | raw file
  1. /**
  2. * Copyright (c) 2005-2012 https://github.com/zhangkaitao
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. */
  6. package com.sishuok.es.common.repository.hibernate.type;
  7. import com.alibaba.fastjson.JSONObject;
  8. import com.alibaba.fastjson.serializer.SerializerFeature;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.hibernate.HibernateException;
  11. import org.hibernate.engine.spi.SessionImplementor;
  12. import org.hibernate.usertype.ParameterizedType;
  13. import org.hibernate.usertype.UserType;
  14. import java.io.Serializable;
  15. import java.sql.PreparedStatement;
  16. import java.sql.ResultSet;
  17. import java.sql.SQLException;
  18. import java.sql.Types;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. import java.util.Properties;
  22. /**
  23. * 将List转换为指定分隔符分隔的字符串存储 List的元素类型只支持常见的数据类型 可参考{@link org.apache.commons.beanutils.ConvertUtilsBean}
  24. * <p>User: Zhang Kaitao
  25. * <p>Date: 13-4-16 上午8:32
  26. * <p>Version: 1.0
  27. */
  28. public class HashMapToStringUserType implements UserType, ParameterizedType, Serializable {
  29. /**
  30. * 默认 java.lang.String
  31. */
  32. private Class keyType;
  33. @Override
  34. public void setParameterValues(Properties parameters) {
  35. String keyType = (String) parameters.get("keyType");
  36. if (!StringUtils.isEmpty(keyType)) {
  37. try {
  38. this.keyType = Class.forName(keyType);
  39. } catch (ClassNotFoundException e) {
  40. throw new HibernateException(e);
  41. }
  42. } else {
  43. this.keyType = String.class;
  44. }
  45. }
  46. @Override
  47. public int[] sqlTypes() {
  48. return new int[]{Types.VARCHAR};
  49. }
  50. @Override
  51. public Class returnedClass() {
  52. return HashMap.class;
  53. }
  54. @Override
  55. public boolean equals(Object o, Object o1) throws HibernateException {
  56. if (o == o1) {
  57. return true;
  58. }
  59. if (o == null || o == null) {
  60. return false;
  61. }
  62. return o.equals(o1);
  63. }
  64. @Override
  65. public int hashCode(Object o) throws HibernateException {
  66. return o.hashCode();
  67. }
  68. /**
  69. * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回
  70. * (此方法要求对克能出现null值进行处理)
  71. * names中包含了当前自定义类型的映射字段名称
  72. *
  73. * @param names
  74. * @param owner
  75. * @return
  76. * @throws org.hibernate.HibernateException
  77. * @throws java.sql.SQLException
  78. */
  79. @Override
  80. public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
  81. String valueStr = rs.getString(names[0]);
  82. if (StringUtils.isEmpty(valueStr)) {
  83. return newMap();
  84. }
  85. Map map = JSONObject.parseObject(valueStr);
  86. Map result = newMap();
  87. try {
  88. for(Object key : map.keySet()) {
  89. Object value = map.get(key);
  90. result.put(keyType.getConstructor(String.class).newInstance(key), value);
  91. }
  92. } catch (Exception e) {
  93. e.printStackTrace();
  94. throw new HibernateException(e);
  95. }
  96. return result;
  97. }
  98. /**
  99. * 本方法将在Hibernate进行数据保存时被调用
  100. * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段
  101. */
  102. @Override
  103. public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
  104. String valueStr;
  105. if (value == null) {
  106. valueStr = "";
  107. } else {
  108. valueStr = JSONObject.toJSONString(value, SerializerFeature.WriteClassName);
  109. }
  110. st.setString(index, valueStr);
  111. }
  112. private Map newMap() {
  113. try {
  114. return HashMap.class.newInstance();
  115. } catch (Exception e) {
  116. throw new HibernateException(e);
  117. }
  118. }
  119. /**
  120. * 提供自定义类型的完全复制方法
  121. * 本方法将用构造返回对象
  122. * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,
  123. * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户
  124. * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过
  125. * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作
  126. * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用
  127. * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作
  128. *
  129. * @param o
  130. * @return
  131. * @throws org.hibernate.HibernateException
  132. */
  133. @Override
  134. public Object deepCopy(Object o) throws HibernateException {
  135. if (o == null) return null;
  136. Map copyMap = newMap();
  137. copyMap.putAll((Map) o);
  138. return copyMap;
  139. }
  140. /**
  141. * 本类型实例是否可变
  142. *
  143. * @return
  144. */
  145. @Override
  146. public boolean isMutable() {
  147. return true;
  148. }
  149. /* 序列化 */
  150. @Override
  151. public Serializable disassemble(Object value) throws HibernateException {
  152. return ((Serializable) value);
  153. }
  154. /* 反序列化 */
  155. @Override
  156. public Object assemble(Serializable cached, Object owner) throws HibernateException {
  157. return cached;
  158. }
  159. @Override
  160. public Object replace(Object original, Object target, Object owner) throws HibernateException {
  161. return original;
  162. }
  163. }