Автор оригинала: Vlad Mihalcea.
Вступление
Проект с открытым исходным кодом типы гибернации позволяет отображать объекты Java или Jackson JsonNode
как свойства объектов JPA или гибернации, и благодаря нашим замечательным участникам мы добавили поддержку для хранения типобезопасных коллекций JSON.
В этой статье вы увидите, как достичь этой цели.
Слава @vlad_mihalcea , библиотека типов гибернации вчера сэкономила мне массу работы, автоматически сопоставив столбец PostgreSQL jsonb с POJO. Блестящая работа 💪
Зависимость от Maven
Прежде всего, вам необходимо настроить следующую зависимость Maven в вашем проекте pom.xml
файл конфигурации:
com.vladmihalcea hibernate-types-55 ${hibernate-types.version}
Если вы используете более старые версии Hibernate, ознакомьтесь с репозиторием hibernate-types
GitHub для получения дополнительной информации о соответствующей зависимости для вашей текущей версии Hibernate.
Модель предметной области
Давайте предположим, что у нас есть следующий тип объекта Location
Java.
public class Location implements Serializable { private String country; private String city; //Getters and setters omitted for brevity @Override public String toString() { return "Location{" + "country='" + country + ''' + ", city='" + city + ''' + '}'; } }
И, одно Событие
сущность:
@Entity(name = "Event") @Table(name = "event") public class Event extends BaseEntity { @Type(type = "json") @Column(columnDefinition = "jsonb") private Location location; @Type(type = "json") @Column(columnDefinition = "jsonb") private ListalternativeLocations = new ArrayList (); //Getters and setters omitted for brevity }
BaseEntity
определяет некоторые базовые свойства (например, @Id
, @Версия
) и несколько пользовательских типов гибернации, среди которых нас интересует JsonType
.
@TypeDefs({ @TypeDef(name = "string-array", typeClass = StringArrayType.class), @TypeDef(name = "int-array", typeClass = IntArrayType.class), @TypeDef(name = "json", typeClass = JsonType.class) }) @MappedSuperclass public class BaseEntity { @Id private Long id; @Version private Integer version; //Getters and setters omitted for brevity }
Для получения более подробной информации об использовании @MappedSuperclass
ознакомьтесь с этой статьей .
Чтобы сохранить как объект Местоположение
, так и Список<Местоположение>
в столбце jsonb
PostgreSQL, нам просто нужно аннотировать свойство местоположение
с помощью @Type(тип)
.
Вот и все!
Время тестирования
При сохранении следующего События
объекта:
Location cluj = new Location(); cluj.setCountry("Romania"); cluj.setCity("Cluj-Napoca"); Location newYork = new Location(); newYork.setCountry("US"); newYork.setCity("New-York"); Location london = new Location(); london.setCountry("UK"); london.setCity("London"); Event event = new Event(); event.setId(1L); event.setLocation(cluj); event.setAlternativeLocations( Arrays.asList(newYork, london) ); entityManager.persist(event);
Hibernate создаст следующую инструкцию SQL INSERT:
INSERT INTO event ( version, alternativeLocations, location, id ) VALUES ( 0, [ {"country":"US","city":"New-York"}, {"country":"UK","city":"London"} ], {"country":"Romania","city":"Cluj-Napoca"}, 1 )
Кроме того, при возврате объекта Событие
свойства местоположения
и | альтернативных местоположений извлекаются правильно:
Событие.найдите(Event.class, вечер);
assertEquals( "Cluj-Napoca", event.getLocation().getCity() ); assertEquals(2, event.getAlternativeLocations().size()); assertEquals( "New-York", event.getAlternativeLocations().get(0).getCity() ); assertEquals( "London", event.getAlternativeLocations().get(1).getCity() );
Круто, правда?
Вывод
Проект hibernate-types
поддерживает не только типы JSON. Вы можете сопоставить типы массивов PostgreSQL или перечисления, относящиеся к PostgreSQL , с возможностью обнуления Символов
или даже предоставить свои собственные неизменяемые пользовательские Типы
для гибернации .