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

2023年 10月 7日 39.9k 0

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

本文主要有以下内容:

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

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

依赖文件如下:


    
        org.springframework.boot
        spring-boot-starter-web
        2.7.14
    
    
        org.projectlombok
        lombok
        1.18.28
    
    
        org.springframework.boot
        spring-boot-starter-data-jpa
        2.7.14
    
    
        mysql
        mysql-connector-java
        8.0.21
        runtime
    

配置文件配置:

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

实体类创建

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

@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注解配合使用

创建枚举类

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

@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。因此我们只需要实现这个接口即可!

@Converter(autoApply = true)
public class MetaStatusEnumConvert implements
        AttributeConverter {
​
    // 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)指定枚举转换器,这样就可以正常工作了。

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

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

@Repository
public interface MetaRepository extends JpaRepository {
    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层代码

@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);
    }
​
}

启动类配置:

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

Postman测试结果如下图:

01_enum_add.png

数据库结果如下:

02_add_result.png

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

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

Spring Data Jpa相关文章:

  • 【Spring Data JPA】Spring Data JPA的简单使用
  • 【Spring Data Jpa中的一对一, 一对多,多对多关系注解】

相关文章

如何删除WordPress中的所有评论
检查WordPress服务器磁盘使用情况的7种简便方法(查找大文件和数据)
如何更改WordPress常量FS_METHOD
如何为区块编辑器、Elementor等构建WordPress文章模板
如何彻底地删除WordPress主题及相关内容
如何使用WordPress搭建一个内网

发布评论