java 枚举保存数据库_在Spring Boot中使用Java枚举自动序列化参数并自动保存数据库 - Dario...

分享在Spring应用程序中使用Java枚举Java Enum映射字段的有效方法。目标:

一个RestController类,以通过不同的HTTP方法(GET,POST等)获取并使用枚举。

一个服务类,它通常用来做一些种类的业务逻辑的实现

一些DAO类(例如JPA Entity和Spring Data Repository),通过保存或检索数据以非常简单的方式与数据库进行通信

我希望我的Web层(RestController)能够执行以下任务:

自动将请求正文字段中的JSON转换(反序列化)为枚举

自动将枚举转换(序列化)为JSON字段

自动将请求参数或路径变量转换为枚举

在DAO层中,我希望具有以下机制:

自动转换JPA实体的字段,该字段是要作为字符串写入数据库的枚举

检索varchar字段并自动映射到JPA实体的Enum字段,而不是字符串

模型:

@Getter

@Setter

@ToString

@EqualsAndHashCode

@Builder

@AllArgsConstructor

@NoArgsConstructor

public class Item {

private String name;

private EnItemType type;

private String explanation;

}

EnItemType是一个枚举它通过类型代码将被解析为正确的数据值,然后在我们的网页和DAO层来管理。目前,仅注意此枚举有一个代码字段,通过它我们可以在整个应用程序中维护引用。

public enum EnItemType {

TYPE1("CODE_1"),

TYPE2("CODE_2"),

TYPE3("CODE_3");

private String code;

private EnItemType(String code) {

this.code=code;

}

@JsonCreator

public static EnItemType decode(final String code) {

return Stream.of(EnItemType.values()).filter(targetEnum -> targetEnum.code.equals(code)).findFirst().orElse(null);

}

@JsonValue

public String getCode() {

return code;

}

}

注意上面代码中:@JsonCreator和@JsonValue批注注解,下面解释。

在 Web层将JSON与枚举序列化和反序列化

对于GET请求,我们必须返回必须以JSON方式进行转换。这就是所谓的JSON序列化操作。

我们可以调用GET方法以按项目类型查找项目,并且可以在path变量中传递Enum代码(而不是Enum名称)。访问:GET http://localhost:8080/item/CODE_1,希望获得下面数据:

{

"name":"A",

"type":"CODE_1",

"explanation":"item A of first type"

}

@JsonCreator注释仅足以将JSON数据解释为枚举,但是如果枚举值是通过路径或请求参数到达的,该怎么办?在这种情况下,我们必须使用从String类型转换为Enum的机制。为此,我实现了以下转换器:

@RequestParameterConverter

public class StringToEnItemTypeConverter implements Converter {

@Override

public EnItemType convert(String source) {

return EnItemType.decode(source);

}

}

这是一个Spring转换器,它使用一个自定义的@RequestParameterConverter批注,我利用该批注利用了组件扫描机制。然后,我实现了注释,如下所示,声明了用该注释注释的方法是Spring Component:

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@Component

public @interface RequestParameterConverter {

}

为了注册转换器,我使用了一个特定的配置类来实现Spring Web MVC接口。此类检索使用我的自定义@RequestParameterConverter注释注释的所有Spring Bean,然后将转换器注册到FormatterRegistry中,该类是专用于在Spring中格式化数据的类。该类如下:

@Configuration

public class WebConfig implements WebMvcConfigurer {

@Autowired

private ListableBeanFactory beanFactory;

@Override

public void addFormatters(FormatterRegistry registry) {

Map components = beanFactory.getBeansWithAnnotation(RequestParameterConverter.class);

components.values().parallelStream().forEach(c -> {

if(c instanceof Converter) {

registry.addConverter((Converter)c);

}

});

}

}

这样,无论您在何处定义了转换器类:如果Spring对其进行了扫描,那么它将被注册并添加到格式化程序集中。

我们已经完成了Web层枚举的使用,现在我们能够:

自动将JSON请求正文字段转换为枚举

自动将枚举转换为JSON字段

自动将请求参数或路径变量转换为枚举

这种转换在RestController中自动进行:

@Api

@RestController

@RequestMapping(

value = "/item",

produces = { MediaType.APPLICATION_JSON_VALUE  })

public class ItemController {

@Autowired

private ItemService itemService;

@GetMapping

public List findItems() {

return itemService.findItems();

}

@GetMapping("/{type}")

public List findItemByType(@PathVariable("type") EnItemType type) {

return itemService.findItemByType(type);

}

@PostMapping

@ResponseStatus(HttpStatus.CREATED)

public Item saveItem(@RequestBody Item item) {

return itemService.saveItem(item);

}

}

DAO层转换

ItemEntity:

@Entity

@Table(name="items")

@Getter

@Setter

public class ItemEntity {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

private String name;

@Column(name="type_code")

private EnItemType type;

private String explanation;

}

在ItemEntity类中,我们直接放置了EnItemType类型的字段,并且希望在插入或更新行时将该字段自动转换为varchar(String)字段,并在执行操作时自动将该字段映射为EnItemType选择操作。

为了实现此目标,我们可以使用JPA提供的名为AttributeConverter的组件。您可以实现此接口,以便在与数据库“对话”时自动将一种数据类型转换为另一种数据类型。我的自定义转换器如下:

/**

* AttributeConvertEnItemTypeype, String>. Implements the following methods :

*

*

convertToDatabaseColumn : (given an Enum returns a String)

*

convertToEntityAttribute : (given a String returns an Enum)

*

*/@Component

@Converter(autoApply = true)

public class EnItemTypeConverter implements AttributeConverter {

@Override

public String convertToDatabaseColumn(final EnItemType attribute) {

return Optional.ofNullable(attribute).map(EnItemType::getCode).orElse(null);

}

@Override

public EnItemType convertToEntityAttribute(final String dbData) {

return EnItemType.decode(dbData);

}

}

它必须实现两个方法:

convertToDatabaseColumn:将枚举转换为字符串,在插入或更新行时使用

convertToEntityAttribute:将来自数据库的数据(仅映射到具有EnItemType枚举的实体中的数据)转换为正确的枚举值

ItemRepository :

public interface ItemRepository extends JpaRepository{

public List findByType(EnItemType type);

}

点击标题见原文。

你可能感兴趣的:(java,枚举保存数据库)