使用休眠映射数组
2022-09-04 06:04:12
你能帮我用Hibernate映射这个类吗?
public class MyClass{
private Long id;
private String name;
private int[] values;
...
}
我正在使用PostgreSQL,表中的列类型是整数[] 我的数组应该如何映射?
你能帮我用Hibernate映射这个类吗?
public class MyClass{
private Long id;
private String name;
private int[] values;
...
}
我正在使用PostgreSQL,表中的列类型是整数[] 我的数组应该如何映射?
Hibernate(和JPA)不能直接映射PostgreSQL数组类型。请参阅此问题,了解如果确实需要保持数据库结构不变,如何继续。此线程具有所需自定义类型的示例。
如果可以更改架构,则可以让休眠创建一个附加表来处理集合 - 。然后,根据您使用的休眠版本:List<Integer>
@ElementCollection
@CollectionOfElements
休眠只能映射基元类型。在 org.hibernate.type 文件夹下的 hibernate jar 包下检查。int 数组不是其中之一。因此,您必须编写一个可以实现 UserType 接口的自定义类型。
public class MyClass{
private Long id;
private String name;
private Integer[] values;
@Type(type = "com.usertype.IntArrayUserType")
public Integer[] getValues(){
return values;
}
public void setValues(Integer[] values){
this.values = values;
}
}
IntArrayUserType.class
package com.usertype.IntArrayUserType;
public class IntArrayUserType implements UserType {
protected static final int[] SQL_TYPES = { Types.ARRAY };
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return this.deepCopy(cached);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Integer[]) this.deepCopy(value);
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == null) {
return y == null;
}
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
if (resultSet.wasNull()) {
return null;
}
if(resultSet.getArray(names[0]) == null){
return new Integer[0];
}
Array array = resultSet.getArray(names[0]);
Integer[] javaArray = (Integer[]) array.getArray();
return javaArray;
}
@Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
Connection connection = statement.getConnection();
if (value == null) {
statement.setNull(index, SQL_TYPES[0]);
} else {
Integer[] castObject = (Integer[]) value;
Array array = connection.createArrayOf("integer", castObject);
statement.setArray(index, array);
}
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
@Override
public Class<Integer[]> returnedClass() {
return Integer[].class;
}
@Override
public int[] sqlTypes() {
return new int[] { Types.ARRAY };
}
查询 MyClass 实体时,可以添加如下内容:
Type intArrayType = new TypeLocatorImpl(new TypeResolver()).custom(IntArrayUserType.class);
Query query = getSession().createSQLQuery("select values from MyClass")
.addScalar("values", intArrayType);
List<Integer[]> results = (List<Integer[]>) query.list();