【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相关文章:

相关推荐
xcl092514 分钟前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌21 分钟前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天30 分钟前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star30 分钟前
LeetCode 141:环形链表
java·算法·leetcode·链表
爱学堂IT分享1 小时前
鹤翔老师pmp项目管理培训认证考试课 (直播录播题库送学时证明)【共58课时】-51CTO学堂
后端
今天AI了吗1 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
王的宝库1 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
数据库小学妹2 小时前
为什么MySQL索引用B+树?从存储底层讲透原理
数据库·mysql·b+树·索引优化·磁盘io·数据库原理
许彰午2 小时前
27-AuthService登录链路
java·低代码·架构
泡海椒2 小时前
JQuick-Curl 性能分析:并发场景下的性能表现与调优,第三方接口调用不只要快写也要稳跑
java·开发语言·okhttp