本站所有的下载内容都包含解压密码,解压密码均为:123456

介绍

开源hibernate-types项目允许你映射JSON,ARRAY YearMonthMonth或数据库特定的列(如INET地址)。

在本文中,我们将看到在使用JPA和Hibernate时如何将PostgreSQL Enum ARRAY类型映射到Java数组实体属性。

Maven依赖

首先,您需要在项目pom.xml配置文件中设置以下Maven依赖项:

<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.3.5</version>
</dependency>

如果您使用的是旧版本的Hibernate(例如5.1或4.3),请查看hibernate-typesGitHub存储库,以获取有关当前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列存储为数组。

现在,我们要将event数据库表映射到以下EventJPA实体:

使用PostgreSQL枚举数组类型的事件实体

要将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 {@Id
private 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在定义setter时更严格,但Hibernate允许您定义setter,以便您可以使用Fluent样式的API构建实体。有关更多详细信息,请查看此文章

该@TypeDef注释被用于定义Java数组类类型和它们相关联的休眠类型之间的映射:

  • Java String[]数组类型由StringArrayType。处理。
  • Java int[]数组类型由。处理IntArrayType
  • Java SensorState[]由处理EnumArrayType。该EnumArrayType.SQL_ARRAY_TYPE参数用于描述用于存储Enum的特定于数据库的列类型。

在SensorStateJava的枚举映射如下:

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()
);

本站所有的下载内容都包含解压密码,解压密码均为:123456

原创文章,转载请注明: 转载自全索引

本文链接地址: 如何使用Hibernate将PostgreSQL Enum ARRAY映射到JPA实体属性

点击量:208