public class MyClass{ private Long id; private String name; private List values; @Id // this is only if your id is really auto generated @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; } @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY) public List getValues() { return values; } ...
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 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 results = (List) query.list();
正如我在本文中解释的那样,使用Hibernate映射数组需要一个自定义类型。
所以,假设您像这样定义IntArrayType :
public class IntArrayType extends AbstractSingleColumnStandardBasicType implements DynamicParameterizedType { public IntArrayType() { super( ArraySqlTypeDescriptor.INSTANCE, IntArrayTypeDescriptor.INSTANCE ); } public String getName() { return "int-array"; } @Override protected boolean registerUnderJavaType() { return true; } @Override public void setParameterValues(Properties parameters) { ((IntArrayTypeDescriptor) getJavaTypeDescriptor()) .setParameterValues(parameters); } }
您还需要ArraySqlTypeDescriptor :
public class ArraySqlTypeDescriptor implements SqlTypeDescriptor { public static final ArraySqlTypeDescriptor INSTANCE = new ArraySqlTypeDescriptor(); @Override public int getSqlType() { return Types.ARRAY; } @Override public boolean canBeRemapped() { return true; } @Override public ValueBinder getBinder( JavaTypeDescriptor javaTypeDescriptor) { return new BasicBinder( javaTypeDescriptor, this) { @Override protected void doBind( PreparedStatement st, X value, int index, WrapperOptions options ) throws SQLException { AbstractArrayTypeDescriptor
和IntArrayTypeDescriptor :
public class IntArrayTypeDescriptor extends AbstractArrayTypeDescriptor { public static final IntArrayTypeDescriptor INSTANCE = new IntArrayTypeDescriptor(); public IntArrayTypeDescriptor() { super( int[].class ); } @Override protected String getSqlArrayType() { return "integer"; } }