postgresql_如何使用Hibernate将PostgreSQL枚举映射到JPA实体属性

postgresql

postgresql

介绍

开源的hibernate-types项目允许您映射JSON,ARRAY, YearMonthMonth或特定于数据库的列(例如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_namessensor_valuessensor_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 {

    @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在定义设置器方面更为严格,但是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()
);

酷吧?

如果您喜欢这篇文章,我敢打赌您也会喜欢我的视频课程

映射PostgreSQL枚举

映射PostgreSQL枚举

结论

hibernate-types项目不只支持ARRAY类型。 您可以映射PostgreSQL特定的Enums,可为空的Character ,JSON,甚至提供自己的不可变Hibernate自定义Types

有关hibernate-types项目的更多详细信息,请参阅本文

翻译自: https://www.javacodegeeks.com/2018/12/map-postgresql-jpa-entity-hibernate.html

postgresql

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot使用PostgreSQL数据库并结合JPA进行开发,可以按照以下步骤进行: 1. 添加依赖 在`pom.xml`文件添加以下依赖: ```xml <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 2. 配置数据源 在`application.properties`文件添加以下配置: ```properties spring.datasource.url=jdbc:postgresql://localhost:5432/mydb spring.datasource.username=myuser spring.datasource.password=mypassword spring.datasource.driver-class-name=org.postgresql.Driver ``` 3. 创建实体类 创建一个实体类,用于映射数据库表的字段,例如: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; // getters and setters } ``` 4. 创建JpaRepository 创建一个继承自`JpaRepository`的接口,用于进行数据库操作,例如: ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` 5. 编写业务逻辑代码 在业务逻辑代码注入`UserRepository`,并使用其提供的方法进行数据库操作,例如: ```java @Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getAllUsers() { return userRepository.findAll(); } public void saveUser(User user) { userRepository.save(user); } // other methods } ``` 至此,Spring Boot整合PostgreSQL并结合JPA进行开发的基本步骤就介绍完了。当然,在实际开发,还有很多需要注意的地方,例如事务管理、异常处理等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值