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

相关推荐
程序员鱼皮2 分钟前
干掉 Claude Code,这个开源 AI 编程工具杀疯了?
前端·后端·计算机·ai·程序员
源代码•宸5 分钟前
Golang基础语法(go语言结构体、go语言数组与切片、go语言条件句、go语言循环)
开发语言·经验分享·后端·算法·golang·go
霍田煜熙9 分钟前
【无标题】
java
q_191328469510 分钟前
基于Springboo和vue开发的企业批量排班系统人脸识别考勤打卡系统
前端·javascript·vue.js·spring boot·mysql·毕业设计·人脸识别
无忧智库12 分钟前
深度拆解:某大型医院“十五五”智慧医院建设方案,如何冲刺互联互通五级乙等?(附技术架构与实施路径)
java·数据库·架构
风吹落叶花飘荡19 分钟前
mysql数据库创建新用户,并只给其必要的权限
数据库·mysql
守护砂之国泰裤辣22 分钟前
Windows+docker下简单kafka测试联调
java·运维·spring boot·docker·容器
代码方舟23 分钟前
Java企业级风控实战:对接天远多头借贷行业风险版API构建信贷评分引擎
java·开发语言
数据小馒头27 分钟前
MySQL文本处理:全库搜索慢?正则清洗难?掌握这 3 个方法
后端