Автор оригинала: Vlad Mihalcea.
Как ранее объяснялось , хотя Hibernate по умолчанию не поддерживает типы столбцов массива базы данных, вы можете легко реализовать пользовательский тип Hibernate ArrayType
. В то время как предыдущее решение работало на PostgreSQL, в этой статье вы увидите, что его довольно легко адаптировать к HSQLDB.
Как реализовать пользовательский #Hibernate Тип массива. @vlad_mihalcea https://t.co/HJGv5uz7zY pic.twitter.com/xTVPbING1C
Предполагая, что в нашей системе есть следующее Событие
сущность:
Нам нужен способ сохранить атрибуты String[]
и Integer[]
entity, поскольку Hibernate по умолчанию не поддерживает типы массивов, зависящие от базы данных.
Для этого мы будем использовать два пользовательских типа гибернации:
@Entity(name = "Event") @Table(name = "event") @TypeDefs({ @TypeDef( name = "string-array", typeClass = VarCharStringArrayType.class ), @TypeDef( name = "int-array", typeClass = IntArrayType.class ), }) public class Event { @Id private Long id; @Type(type = "string-array") @Column( name = "sensor_names", columnDefinition = "VARCHAR(100) ARRAY" ) private String[] sensorNames; @Type(type = "int-array") @Column( name = "sensor_values", columnDefinition = "INT ARRAY" ) private Integer[] sensorValues; //Getters and setters omitted for brevity }
Код для Строкового типа массива
и Типа IntArrayType
был описан ранее в этой статье поэтому мы не будем повторять его здесь.
Единственное отличие заключается в том, что мы используем Тип массива строк VarChar
сейчас, поскольку HSQLDB не поддерживает тип столбца TEXT
базы данных:
public class VarCharStringArrayType extends StringArrayType { public static final VarCharStringArrayType INSTANCE = new VarCharStringArrayType(); public VarCharStringArrayType() { super( VarCharStringArrayTypeDescriptor.INSTANCE ); } }
Также дескриптор типа массива строк VarChar
тоже довольно тривиален:
public class VarCharStringArrayTypeDescriptor extends StringArrayTypeDescriptor { public static final VarCharStringArrayTypeDescriptor INSTANCE = new VarCharStringArrayTypeDescriptor(); @Override public String getSqlArrayType() { return "varchar"; } }
И, вот оно что!
Вам не нужно создавать все эти типы вручную. Вы можете просто получить их через Maven Central, используя следующую зависимость:
com.vladmihalcea hibernate-types-55 ${hibernate-types.version}
Для получения дополнительной информации ознакомьтесь с проектом с открытым исходным кодом типа hibernate .
При сохранении двух Событий
сущностей:
Event nullEvent = new Event(); nullEvent.setId(0L); entityManager.persist(nullEvent); Event event = new Event(); event.setId(1L); event.setSensorNames( new String[]{"Temperature", "Pressure"} ); event.setSensorValues( new Integer[]{12, 756} ); entityManager.persist(event);
Hibernate выполнит следующие инструкции SQL INSERT:
INSERT INTO event ( sensor_names, sensor_values, id ) VALUES ( NULL(ARRAY), NULL(ARRAY), 0 ) INSERT INTO event ( sensor_names, sensor_values, id ) VALUES ( ARRAY['Temperature','Pressure'], ARRAY[12,756], 1 )
При извлечении объекта Событие
:
Event event = entityManager.find(Event.class, 1L); assertArrayEquals(new String[]{"Temperature", "Pressure"}, event.getSensorNames()); assertArrayEquals(new Integer[]{12, 756}, event.getSensorValues());
Hibernate может правильно сопоставить базовый тип столбца МАССИВА с массивами String[]
и Integer[]
Java.
Вы также можете использовать JPQL для фильтрации результатов на основе заданного массива Java:
Event event = entityManager .createQuery( "select e " + "from Event e " + "where e.sensorNames = :sensorNames", Event.class) .setParameter "sensorNames", new String[]{"Temperature", "Pressure"} ) .getSingleResult();
Как показано в этой статье, сопоставление типов столбцов МАССИВА с массивами Java String[]
или Integer
довольно просто при использовании Hibernate.