SpringBoot Entity中枚举类型详细使用介绍

 更新时间:2022年10月20日 15:13:13   作者:IT利刃出鞘  
本文介绍SpringBoot如何在Entity(DAO)中使用枚举类型。(本文使用MyBatis-Plus)。在实际开发中,经常会遇到表示类型或者状态的情况,比如:有三种支付方式:微信、支付宝、银联。本文介绍如何这种场景的方案对比,并用实例来介绍如何用枚举这种最优雅的来表示

简介方案对比

本处列举表示类型或状态的常用方法的对比。

法1:使用数字表示(不推荐)

//1:支付宝支付;2:微信支付;3:银行卡支付
private Integer payType;

这种方法的缺点:可读性极差,排查问题也麻烦。比如:前端页面上看到了2这个类型,还要看接口文档或者问后端这是什么意思,浪费时间!

法2:使用字符串表示(不推荐)

//ALIPAY:支付宝;WECHAT_PAY:微信;BANK_CARD_PAY:银行卡支付
private String payType;

这种方式比法1好一些了,提高了数据库的可读性和排查问题速度。

缺点:难以控制不允许数据库的pay_type为空字符串这种情况;支持的类型没有限制死,前端传个其他的字符串也能存入数据库。

法3:使用枚举表示(推荐)

枚举是这种场景最好的方案(枚举本身就是为了表示可穷举类型而发明出来的!)。

定义一个枚举类

package com.example.demo.order.enums;
import lombok.Getter;
@Getter
public enum PayTypeEnum {
    ALIPAY("支付宝"),
    WECHAT_PAY("微信支付"),
    BANK_CARD_PAY("银行卡支付"),
    ;
    private final String description;
    PayTypeEnum(String description) {
        this.description = description;
    }
}

Entity中定义枚举类型字段

private PayTypeEnum payType;

优点

  • 可读性极高,排查问题很快(比如:前端页面上看到ALIPAY这个类型,一眼就能知道是支付宝)
  • 可以控制不允许数据库的pay_type为空字符串这种情况(因为枚举字段不可能有空字符串)
  • 支持的类型限制死,前端传个其他的字符串无法存入数据库。

枚举用法示例

建表

CREATE TABLE `t_order` (
  `id` bigint NOT NULL COMMENT 'ID',
  `order_no` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '订单号',
  `pay_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '支付类型。ALIPAY:支付宝;WECHAT_PAY:微信;BANK_CARD_PAY:银行卡支付。',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单';

pay_type字段加了NOT NULL限制。

Entity

package com.example.demo.order.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.demo.order.enums.PayTypeEnum;
import lombok.Data;
@Data
@TableName("t_order")
public class Order {
    private Long id;
    private String orderNo;
    private PayTypeEnum payType;
}

Enum

package com.example.demo.order.enums;
import lombok.Getter;
@Getter
public enum PayTypeEnum {
    ALIPAY("支付宝"),
    WECHAT_PAY("微信支付"),
    BANK_CARD_PAY("银行卡支付"),
    ;
    private final String description;
    PayTypeEnum(String description) {
        this.description = description;
    }
}

Controller

package com.example.demo.order.controller;
import com.example.demo.order.entity.Order;
import com.example.demo.order.service.OrderService;
import com.example.demo.user.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @PostMapping("pay")
    public void pay(@RequestBody Order order) {
        orderService.save(order);
    }
}

Service

接口

package com.example.demo.order.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.order.entity.Order;
public interface OrderService extends IService<Order> {
}

实现

package com.example.demo.order.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.order.entity.Order;
import com.example.demo.order.mapper.OrderMapper;
import com.example.demo.order.service.OrderService;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
}

Mapper

package com.example.demo.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.order.entity.Order;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderMapper extends BaseMapper<Order> {
}

测试

1.正常操作

写入成功,枚举的name()方法的值会写到数据库。

后端结果

数据库结果

2.前端传空字符串

此时会报错,因为枚举中没有对应空字符串的。

后端结果(无法将空字符串反序列化为枚举对象)

2022-09-10 10:14:30.406  WARN 128760 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `com.example.demo.order.enums.PayTypeEnum` from String "": not one of the values accepted for Enum class: [ALIPAY, BANK_CARD_PAY, WECHAT_PAY]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.example.demo.order.enums.PayTypeEnum` from String "": not one of the values accepted for Enum class: [ALIPAY, BANK_CARD_PAY, WECHAT_PAY]
 at [Source: (PushbackInputStream); line: 4, column: 16] (through reference chain: com.example.demo.order.entity.Order["payType"])]

数据库结果(没写入数据)

3.前端传null

后端结果(pay_type为null,写入数据库时报错)

2022-09-10 10:24:20.514 ERROR 128760 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: 
### Error updating database.  Cause: java.sql.SQLException: Field 'pay_type' doesn't have a default value
### The error may exist in com/example/demo/order/mapper/OrderMapper.java (best guess)
### The error may involve com.example.demo.order.mapper.OrderMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO t_order  ( id, order_no )  VALUES  ( ?, ? )
### Cause: java.sql.SQLException: Field 'pay_type' doesn't have a default value
; Field 'pay_type' doesn't have a default value; nested exception is java.sql.SQLException: Field 'pay_type' doesn't have a default value] with root cause
 
java.sql.SQLException: Field 'pay_type' doesn't have a default value
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.25.jar:8.0.25]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.25.jar:8.0.25]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.25.jar:8.0.25]
    at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:370) ~[mysql-connector-java-8.0.25.jar:8.0.25]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) ~[HikariCP-3.4.5.jar:na]
    ......

数据库结果(没写入数据)

到此这篇关于SpringBoot Entity中枚举类型详细使用介绍的文章就介绍到这了,更多相关SpringBoot Entity内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JAVA实现生成短链接的示例代码

    JAVA实现生成短链接的示例代码

    短链接就是将长度较长的链接压缩成较短的链接,本文就来介绍一下JAVA实现生成短链接的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Java类加载器之ContextClassLoader详解

    Java类加载器之ContextClassLoader详解

    这篇文章主要介绍了Java类加载器之ContextClassLoader详解,ContextClassLoader是一种与线程相关的类加载器,类似ThreadLocal,每个线程对应一个上下文类加载器,需要的朋友可以参考下
    2023-10-10
  • Java与Python之间使用jython工具类实现数据交互

    Java与Python之间使用jython工具类实现数据交互

    今天小编就为大家分享一篇关于Java与Python之间使用jython工具类实现数据交互,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Mybatis Plus条件构造器ConditionConstructor用法实例解析

    Mybatis Plus条件构造器ConditionConstructor用法实例解析

    这篇文章主要介绍了Mybatis Plus条件构造器ConditionConstructor用法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • SpringBoot整合Mail发送邮件功能

    SpringBoot整合Mail发送邮件功能

    我们在网站上注册账号的时候一般需要获取验证码,而这个验证码一般发送在你的手机号上还有的是发送在你的邮箱中,注册,账号密码…都需要用到验证,今天就演示一下如何用SpringBoot整合Mail发送邮箱
    2021-11-11
  • Java如何使用spire进行word文档的替换详解

    Java如何使用spire进行word文档的替换详解

    创作一份文案经常会高频率地使用某些词汇,如地名、人名、人物职位等,若表述有误,就需要整体撤换,下面这篇文章主要给大家介绍了关于Java如何使用spire进行word文档的替换的相关资料,需要的朋友可以参考下
    2023-01-01
  • Spring MVC学习教程之RequestMappingHandlerMapping匹配

    Spring MVC学习教程之RequestMappingHandlerMapping匹配

    这篇文章主要给大家介绍了关于Spring MVC学习教程之RequestMappingHandlerMapping匹配的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-11-11
  • Java递归实现字符串全排列与全组合

    Java递归实现字符串全排列与全组合

    这篇文章主要为大家详细介绍了Java递归实现字符串全排列与全组合,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • Java面向对象特性深入刨析封装

    Java面向对象特性深入刨析封装

    封装是一个非常广泛的概念,小到一个属性的封装,大到一个框架或者一个项目的封装,下面这篇文章主要给大家介绍了关于java中封装的那点事,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Java 读取、获取配置文件.properties中的数据

    Java 读取、获取配置文件.properties中的数据

    这篇文章主要介绍了Java 读取、获取配置文件.properties中的数据,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09

最新评论