介绍
 开源的hibernate-types项目允许您映射JSON,ARRAY, YearMonth , Month或数据库特定的列(例如INET地址)。 
在本文中,我们将看到使用JPA和Hibernate时如何将PostgreSQL Enum类型映射到Java数组。
Maven依赖
 首先,您需要在项目pom.xml配置文件中设置以下Maven依赖项: 
<dependency><groupId>com.vladmihalcea</groupId><artifactId>hibernate-types-52</artifactId><version>2.3.5</version>
</dependency> 如果您使用的是较早版本的Hibernate,请查看hibernate-types GitHub存储库 ,以获取有关当前Hibernate版本的匹配依赖项的更多信息。 
领域模型
 假设我们在数据库模式中具有以下sensor_state PostgreSQL枚举: 
CREATE TYPE sensor_state AS ENUM ('ONLINE','OFFLINE','UNKNOWN'
);我们的应用程序需要将事件存储在以下数据库表中:
CREATE TABLE event (id bigint NOT NULL,sensor_names text[],sensor_values integer[],sensor_states sensor_state[],CONSTRAINT event_pkey PRIMARY KEY (id)
) 请注意, sensor_names , sensor_values和sensor_states列存储为数组。 要将PostgreSQL数组列类型映射到Java数组,您需要一个自定义的Hibernate类型,因为内置类型不支持持久化特定于数据库的数组。 
 但是,由于有了hibernate-types库,您可以轻松地将event表映射到以下Event实体: 
@Entity(name = "Event")
@Table(name = "event")
@TypeDefs({@TypeDef(typeClass = StringArrayType.class,defaultForType = String[].class),@TypeDef(typeClass = IntArrayType.class,defaultForType = int[].class),@TypeDef(typeClass = EnumArrayType.class,defaultForType = SensorState[].class,parameters = {@Parameter(name = EnumArrayType.SQL_ARRAY_TYPE,value = "sensor_state")})
})
public class Event {@Idprivate Long id;@Column(name = "sensor_names",columnDefinition = "text[]")private String[] sensorNames;@Column(name = "sensor_values",columnDefinition = "integer[]")private int[] sensorValues;@Column(name = "sensor_states",columnDefinition = "sensor_state[]")private SensorState[] sensorStates;public Long getId() {return id;}public Event setId(Long id) {this.id = id;return this;}public String[] getSensorNames() {return sensorNames;}public Event setSensorNames(String[] sensorNames) {this.sensorNames = sensorNames;return this;}public int[] getSensorValues() {return sensorValues;}public Event setSensorValues(int[] sensorValues) {this.sensorValues = sensorValues;return this;}public SensorState[] getSensorStates() {return sensorStates;}public Event setSensorStates(SensorState[] sensorStates) {this.sensorStates = sensorStates;return this;}
} 注意Event实体使用的Fluent风格的API。 尽管JPA在定义设置器方面更为严格,但是Hibernate允许您定义设置器,以便您可以使用Fluent风格的API来构建实体。 有关更多详细信息,请查看本文 。 
 @TypeDef批注用于定义Java数组类类型及其关联的Hibernate类型之间的映射: 
-  Java String[]数组类型由StringArrayType处理。
-  Java int[]数组类型由IntArrayType处理
-  Java SensorState[]由EnumArrayType处理。EnumArrayType.SQL_ARRAY_TYPE参数用于描述用于存储Enum的特定于数据库的列类型。
 SensorState Java枚举映射如下: 
public enum SensorState {ONLINE, OFFLINE, UNKNOWN;
}测试时间
 现在,当存储以下Event实体时: 
entityManager.persist(new Event().setId(1L).setSensorNames(new String[]{"Temperature", "Pressure"}).setSensorValues(new int[]{12, 756}).setSensorStates(new SensorState[]{SensorState.ONLINE, SensorState.OFFLINE,SensorState.ONLINE,     SensorState.UNKNOWN})   
);Hibernate执行以下SQL INSERT语句:
Query:["insert into event (sensor_names, sensor_states, sensor_values, id) values (?, ?, ?, ?)
"], 
Params:[({"Temperature","Pressure"}, {"ONLINE","OFFLINE","ONLINE","UNKNOWN"}, {"12","756"}, 1
)] 并且,当我们获取Event实体时,我们可以看到所有属性均已正确获取 
Event event = entityManager.find(Event.class, 1L);assertArrayEquals(new String[]{"Temperature", "Pressure"}, event.getSensorNames()
);assertArrayEquals(new int[]{12, 756}, event.getSensorValues()
);assertArrayEquals(new SensorState[]{SensorState.ONLINE, SensorState.OFFLINE, SensorState.ONLINE, SensorState.UNKNOWN}, event.getSensorStates()
);酷吧?
如果您喜欢这篇文章,我敢打赌您也会喜欢我的书和视频课程 。
  
  
结论
 hibernate-types项目不只支持ARRAY类型。 您可以映射PostgreSQL特定的Enums,可为空的Character ,JSON,甚至提供您自己的不可变的Hibernate自定义Types 。 
 有关hibernate-types项目的更多详细信息,请参阅本文 。 
翻译自: https://www.javacodegeeks.com/2018/12/map-postgresql-jpa-entity-hibernate.html