【Spring Data Jpa 03】Spring Data Jpa对枚举类型的处理

在日常的开发中,我们常常经常会使用到枚举类型。如前端用户性别显示为男女,而数据库中存储的是0或者1。本文在数据持久层是JPA的情况下,记录如何使用枚举类型。

本文主要有以下内容:

  • Spring Data Jpa对枚举类型的处理

前置条件:具体过程省略,创建spring boot工程,并引入相关依赖。

依赖文件如下:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.7.14</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.28</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.7.14</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

配置文件配置:

yml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/datajpa?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true
    database-platform: org.hibernate.dialect.MySQL8Dialect
    database: mysql
    generate-ddl: true
    open-in-view: true
# 这里的配置是为了解决如果我们的实体类中有MySQL关键字相同的属性,添加此配置可以建表成功。但是一般是不要使用相关的关键字属性。
#    properties:
#      hibernate:
#        globally_quoted_identifiers: true
server:
  port: 8585

实体类创建

创建一个实体类,代码如下

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "table_meta")
@EntityListeners(AuditingEntityListener.class)
public class MetaEntity {
​
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "meta_id")
    private Long metaId;
​
    @Column(name = "type_id")
    private Long typeId;
​
    @Column(name = "key_name")
    private Long keyName;
​
    @Column(name = "meta_status",nullable = false)
    private MetaStatusEnum metaStatus;
​
    @CreatedDate
    @Column(name = "created_time",nullable = false)
    private Date createdTime;
​
}
  • @Entity@Table:用于标识这是一个实体类且与之关联的数据表名。
  • @EntityListeners(AuditingEntityListener.class):用于自动填充createdTime属性
  • @CreatedDate:表示此纪录的创建时间,和本文所讨论的内容无关,可忽略,该注解需要在类上添加@EntityListerers注解配合使用

创建枚举类

在实体类中使用的枚举类如下:

java 复制代码
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum MetaStatusEnum {
    AVAILABLE("未使用", 1),
    USED("已用", 2),
    INACTIVE("已经注销", 3);
​
    private String desc;
    private Integer code;
​
    public static MetaStatusEnum convert(Integer code) {
        if (code == null) {
            return null;
        }
        return Stream.of(values())
                .filter(bean -> bean.code.equals(code))
                .findAny()
                .orElse(null);
    }
}

在此类中定义了一个convert方法用于通过code得到对应的枚举对象,

创建枚举类转换器

jpa中,提供了一个AttributeConverter接口,用于处理枚举类到DB或者DB到JavaBean。因此我们只需要实现这个接口即可!

java 复制代码
@Converter(autoApply = true)
public class MetaStatusEnumConvert implements
        AttributeConverter<MetaStatusEnum, Integer> {
​
    // enum to DB value
    @Override
    public Integer convertToDatabaseColumn(MetaStatusEnum metaStatusEnum) {
        return metaStatusEnum.getCode();
    }
​
    // db to javaBean
    @Override
    public MetaStatusEnum convertToEntityAttribute(Integer code) {
        return MetaStatusEnum.convert(code);
    }
}
  • convertToDatabaseColumn():将我们的枚举对象转换为数据库中存储的值。
  • convertToEntityAttribute():将数据库中存储的值转换为枚举对象
  • 使用@Converter(autoApply = true)标注此类

在写完转换器之后,在实体类上的枚举属性上添加@Convert(converter = MetaStatusEnumConvert.class)指定枚举转换器,这样就可以正常工作了。

java 复制代码
@Column(name = "meta_status",nullable = false)
@Convert(converter = MetaStatusEnumConvert.class)
private MetaStatusEnum metaStatus;

完成上述工作后,简单定义一下daoservice接口代码。

java 复制代码
@Repository
public interface MetaRepository extends JpaRepository<MetaEntity,Long> {
    MetaEntity findMetaEntityByMetaId(Long id);
}
public interface MetaServiceInt {
    MetaEntity findMetaEntityByMetaId(Long id);
    MetaEntity insertMeta(MetaEntity entity);
}
// service实现代码
@Service
public class MetaServiceImpl implements MetaServiceInt {
    @Resource
    MetaRepository metaRepository;
    @Override
    public MetaEntity findMetaEntityByMetaId(Long id) {
        return metaRepository.findMetaEntityByMetaId(id);
    }
    @Override
    public MetaEntity insertMeta(MetaEntity entity) {
        return metaRepository.save(entity);
    }
}

接下来是controller层代码

java 复制代码
@RestController
@CrossOrigin(allowedHeaders = "*", origins = "*")
@RequestMapping("meta/")
public class MetaController {
​
    @Resource
    MetaServiceInt metaService;
​
    @GetMapping("find.do")
    public MetaEntity findMetaByMetaId(Long metaId) {
        return metaService.findMetaEntityByMetaId(metaId);
    }
​
    @PostMapping("insert.do")
    public MetaEntity insertMeta(MetaEntity entity) {
        return metaService.insertMeta(entity);
    }
​
}

启动类配置:

java 复制代码
@SpringBootApplication
@EntityScan("com.jpa.tutorial.entity")
@EnableJpaAuditing
public class JpaApplication {
    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class);
    }
}
  • @EnableJpaAuditing:是为了能够让@CreatedDate正常工作。

Postman测试结果如下图:

数据库结果如下:

可以看到接口达到预期效果:

  • createdTime:自动填充
  • 枚举类型正常工作

Spring Data Jpa相关文章:

相关推荐
万亿少女的梦1689 分钟前
基于Spring Boot的楚雄旅游景区门票售卖系统设计与实现
java·spring boot·mysql·vue·系统设计
不会写代码的ys10 分钟前
C++复习篇
java·开发语言·c++
雨师@14 分钟前
go语言项目--实例化(图书管理)--005
开发语言·后端·golang
Aspiresky25 分钟前
探索Rust语言之引用
开发语言·后端·rust
我是个假程序员34 分钟前
实例化动作脚本类,并执行,执行类似N_F1_SAVE.java这种
java·nc
青山木1 小时前
Hot 100 --- LRU 缓存
java·数据结构·算法·leetcode·链表·缓存·哈希
花生了什么事o1 小时前
Java 线程池:从参数到拒绝策略
java·jvm
冰暮流星1 小时前
flask之app.py讲解
后端·python·flask
长孙豪翔1 小时前
引发事件的问题
java·linux·数据库
happyprince1 小时前
09-vLLM KV Cache 系统完整分析
java·spring·vllm