Автор оригинала: 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.