接下来我将详细讲解"简要分析Java的Hibernate框架中的自定义类型"的完整攻略。
简介
Java的Hibernate框架是非常流行的ORM框架,它可以帮助Java开发人员轻松和高效的操作关系型数据库。其中一个重要的特性就是类型映射,Hibernate框架支持大部分的Java数据类型和关系型数据库中的数据类型之间的映射。但是有时我们需要对数据类型进行更加精细的控制,以满足一些业务需求,这时自定义类型就派上用场了。
Hibernate框架提供了自定义类型的支持,可以让开发人员根据需要来创建自己的数据类型,并且可以与Hibernate框架无缝集成,实现高度自定义化的数据类型转换和映射。
自定义类型的实现
实现自定义类型
Hibernate框架的自定义类型,需要实现org.hibernate.usertype.UserType接口,其中重要的方法有五个:
public class MyCustomType implements UserType {
public int[] sqlTypes() {...}
public Class<?> returnedClass() {...}
public boolean equals(final Object x, final Object y) {...}
public int hashCode(final Object x) {...}
public Object nullSafeGet(final ResultSet rs, final String[] names, final SharedSessionContractImplementor session, final Object owner) {...}
public void nullSafeSet(final PreparedStatement st, final Object value, final int index, final SharedSessionContractImplementor session) {...}
public Object deepCopy(final Object value) {...}
public boolean isMutable() {...}
public Serializable disassemble(final Object value) {...}
public Object assemble(final Serializable cached, final Object owner) {...}
public Object replace(final Object original, final Object target, final Object owner) {...}
}
其中,sqlTypes()方法会返回该自定义类型所对应的SQL类型,在进行数据类型转换时需要用到这个方法;returnedClass()方法返回自定义类型所对应的Java类型;equals()和hashCode()方法用于判断两个对象是否相等和计算哈希值;nullSafeGet()方法将取出的数据库值(Object)转换成自定义类型(Java类),并返回转换后的值;nullSafeSet()方法将自定义类型(Java类)转换成数据库类型(Object)然后存入数据库。
注册自定义类型
自定义类型实现完成后,需要将其与Hibernate框架进行整合,注册自定义类型有两种方式:
- 在Hibernate的配置文件中(xml配置文件)定义
<property name="hibernate.types_registered">
com.example.MyCustomType
</property>
- 在Java代码中进行注册
Type type = new TypeLocatorImpl(StandardServiceInitiators.LIST).locate("com.example.MyCustomType");
if (type!=null) {
TypeFactory.getTypeResolver().registerTypeOverride(type);
}
示例
示例1:实现自定义SQLEnumType枚举类型
例如我们需要将一个Java枚举类型映射成一个整数字段,需要在Hibernate框架中定义一个自定义类型:
public class SQLEnumType implements UserType {
public int[] sqlTypes() {
return new int[]{Types.VARCHAR};
}
public Class<SQLEnumType> returnedClass() {
return SQLEnumType.class;
}
public Object nullSafeGet(ResultSet rs, String[] names,
SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
String name = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
}
for (SQLEnumType value : EnumSet.allOf(SQLEnumType.class)) {
if (value.toString().equals(name)) {
return value;
}
}
throw new HibernateException("Unknown value '" + name + "' for SQLEnumType enum");
}
public void nullSafeSet(PreparedStatement st, Object value, int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, value.toString());
}
}
public boolean equals(Object o, Object o1) throws HibernateException {
return Objects.equals(o, o1);
}
public int hashCode(Object o) throws HibernateException {
return Objects.hashCode(o);
}
public Object deepCopy(Object o) throws HibernateException {
return o;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object o) throws HibernateException {
return (Serializable) o;
}
public Object assemble(Serializable serializable, Object o) throws HibernateException {
return serializable;
}
public Object replace(Object o, Object o1, Object o2) throws HibernateException {
return o;
}
}
然后在Hibernate的配置文件中注册自定义类型:
<property name="hibernate.types_registered">
com.example.hibernatedemo.SQLEnumType
</property>
最后,在实体类中使用自定义类型:
@Entity
@Table(name = "users")
public class User {
// 其他属性省略
// ...
@Type(type = "com.example.hibernatedemo.SQLEnumType")
@Column(name = "gender")
private Gender gender;
}
示例2:实现自定义JsonType类型
我们可以使用Gson库将Java对象序列化成Json字符串,但是在Hibernate中我们需要将Json字符串存到数据库中,这时就可以使用自定义JsonType类型。
public class JsonType implements UserType {
private static final Gson GSON = new Gson();
@Override
public int[] sqlTypes() {
return new int[] { Types.JAVA_OBJECT };
}
@Override
public Class<?> returnedClass() {
return Object.class;
}
@Override
public boolean equals(Object x, Object y) {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) {
return Objects.hashCode(x);
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
String json = rs.getString(names[0]);
return json == null ? null : GSON.fromJson(json, returnedClass());
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
if (value == null) {
st.setNull(index, Types.OTHER);
} else {
String json = GSON.toJson(value);
st.setObject(index, json, Types.OTHER);
}
}
@Override
public Object deepCopy(Object value) {
if (value != null) {
String json = GSON.toJson(value);
return GSON.fromJson(json, returnedClass());
}
return null;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) {
return GSON.toJson(value);
}
@Override
public Object assemble(Serializable cached, Object owner) {
String json = (String) cached;
return GSON.fromJson(json, returnedClass());
}
@Override
public Object replace(Object original, Object target, Object owner) {
return original;
}
}
然后注册自定义类型:
Type type = new TypeLocatorImpl(StandardServiceInitiators.LIST).locate("com.example.JsonType");
if (type != null) {
TypeFactory.getTypeResolver().registerTypeOverride(type);
}
或者在Hibernate的配置文件中注册自定义类型:
<property name="hibernate.types_registered">
com.example.JsonType
</property>
在实体类中使用自定义类型:
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
@Type(type = "com.example.JsonType")
@Column(columnDefinition = "json")
private List<String> roles;
// getter和setter方法
}
以上就是关于"简要分析Java的Hibernate框架中的自定义类型"的完整攻略,希望对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简要分析Java的Hibernate框架中的自定义类型 - Python技术站