在日常的开发中,我们常常经常会使用到枚举类型。如前端用户性别显示为男女,而数据库中存储的是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;
完成上述工作后,简单定义一下dao
和service
接口代码。
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相关文章: