Hibernate

UserType

hibernate中可以自定义映射属性的类型,例如我实体类中是一个List类型的字段,我想将其存储成json字符串。可以同时实现UserType接口,实现自定义的JsonType。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**
* 数据库中字段类型,取Types类中的值
* @see java.sql.Types
* @return int[] the typecodes
*/
int[] sqlTypes();

/**
*nullSafeGet 放回的类型,也是实体类中字段类型
* @return Class
*/
Class returnedClass();

/**
*
* 对比实体对象和数据库对象
* @param x
* @param y
* @return boolean
*/
boolean equals(Object x, Object y) throws HibernateException;

/**
* Get a hashcode for the instance, consistent with persistence "equality"
*/
int hashCode(Object x) throws HibernateException;

/**
* 将该列数据库类型化为实体类中的类型
* @param rs a JDBC result set
* @param names the column names
* @param session
*@param owner the containing entity @return Object
* @throws HibernateException
* @throws SQLException
*/
Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException;

/**
*
* 将实体属性类型转成数据库类型保存
* @param st a JDBC prepared statement
* @param value the object to write
* @param index statement parameter index
* @param session
* @throws HibernateException
* @throws SQLException
*/
void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException;

/**
*
* 用户自己定义的类型的深复制方法
* @param value the object to be cloned, which may be null
* @return Object a copy
*/
Object deepCopy(Object value) throws HibernateException;

/**
* 是否可变
*
* @return boolean
*/
boolean isMutable();

/**
* 副本对象,可变对象要保证是value的深复制对象
*
* @param value the object to be cached
* @return a cachable representation of the object
* @throws HibernateException
*/
Serializable disassemble(Object value) throws HibernateException;

/**
* cached对象可变的话,可缓存对象的深复制
*
* @param cached the object to be cached
* @param owner the owner of the cached object
* @return a reconstructed object from the cachable representation
* @throws HibernateException
*/
Object assemble(Serializable cached, Object owner) throws HibernateException;

/**
* During merge, replace the existing (target) value in the entity we are merging to
* with a new (original) value from the detached entity we are merging. For immutable
* objects, or null values, it is safe to simply return the first parameter. For
* mutable objects, it is safe to return a copy of the first parameter. For objects
* with component values, it might make sense to recursively replace component values.
*
* @param original the value from the detached entity being merged
* @param target the value in the managed entity
* @return the value to be merged
*/
Object replace(Object original, Object target, Object owner) throws HibernateException;

JsonType实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class JsonType implements UserType {
@Override
public int[] sqlTypes() {
return new int[]{Types.CLOB};
}

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

@Override
public boolean equals(Object o, Object o1) throws HibernateException {
return JSONUtils.toJSONString(o).equals(o1);
}

@Override
public int hashCode(Object o) throws HibernateException {
return JSONUtils.toJSONString(o).hashCode();
}

@Override
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException, SQLException {
String json = resultSet.getString(strings[0]);
if (StringUtils.isEmpty(json)) {
return null;
}
return JSONUtils.parse(json);
}

@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SharedSessionContractImplementor sharedSessionContractImplementor) throws HibernateException, SQLException {
if (o == null) {
preparedStatement.setString(i, "");
} else {
preparedStatement.setString(i, JSONUtils.toJSONString(o));
}
}

@Override
public Object deepCopy(Object o) throws HibernateException {
String s = JSONUtils.toJSONString(o);
return JSONUtils.parse(s);
}

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

@Override
public Serializable disassemble(Object o) throws HibernateException {
return (Serializable) deepCopy(o);
}

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

@Override
public Object replace(Object o, Object o1, Object o2) throws HibernateException {
return deepCopy(o);
}
}

使用

1
2
3
4
5
6
7
@Entity
@TypeDef(name = "json",typeClass = JsonType.class)
public class Entity implements IEntity<String> {
@Type(type = "json")
private List<Integer> ids;
...
}