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

目录
  • 简介方案对比
  • 枚举用法示例
    • 建表
    • Entity
    • Enum
    • Controller
    • Service
    • Mapper
  • 测试
    • 1.正常操作
    • 2.前端传空字符串
    • 3.前端传null

简介方案对比

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

法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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot~ObjectMapper~dto到entity的自动赋值

    实体与Dto自动赋值 在开发的过程中,实体之间相互赋值是很正常的事,但是我们一般的方法都通过set和get方法来进行的,如果要赋值的字段少那还行,但是需要赋值的字段超过10个,那就是个灾难,你会看到整屏代码中全是set和get方法. 两个实体属性字段几乎完全相同 两个字体有部分字段相同 源实体只有部分字段赋值,目标实体有完整的值 第一种情况 对于第1点来说,我们用到最多的就是entity和dto之间的转换了,这个我们可以使用Spring的工具类BeanUtils来解决,这里要注意的一点是,==第

  • SpringBoot项目中建议关闭Open-EntityManager-in-view原因

    目录 前言 问题背景 OPEN-ENTITYMANAGER-IN-VIEW的前世今生 问题的真实原因 解决方案 建议关闭OPEN-ENTITYMANAGER-IN-VIEW 结语 前言 一天,开发突然找过来说KLock分布式锁失效了,高并发情况下没有锁住请求,导致数据库抛乐观锁的异常.一开始我是不信的,KLock是经过线上大量验证的,怎么会出现这么低级的问题呢?然后,协助开发一起排查了一下午,最后经过不懈努力和一探到底的摸索精神最终查明不是KLock锁的问题,问题出在Spring Data Jp

  • springboot jpaRepository为何一定要对Entity序列化

    目录 springboot jpaRepository对Entity序列化 1. 问题 2. 写个基本的JpaRepository的使用 最后一个简单的测试 springboot 使用JpaRepository springboot jpaRepository对Entity序列化 1. 问题 一开始,我没有对实体类Inventory序列化,导致在使用内嵌数据库H2的JPA时,它直接安装字母序列把表Inventory的字段生成. 举例,原来我按照 inventory(id, name, quant

  • SpringBoot:JPA + AuditingEntityListener时区设置方式

    目录 JPA + AuditingEntityListener时区设置 可在应用配置中添加如下配置 @EntityListeners(AuditingEntityListener.class)介绍 @EntityListeners AuditingEntityListener.class JPA + AuditingEntityListener时区设置 在SpringBoot项目中,如果应用启用了EnableJpaAuditing并且使用AuditingEntityListener对实体的创建时

  • 新建springboot项目时,entityManagerFactory报错的解决

    目录 新建springboot项目entityManagerFactory报错 解决办法 spring生成EntityManagerFactory三种方式 1.LocalEntityManagerFactoryBean 2.从JNDI获取EntityManagerFactory 3.LocalContainerEntityManagerFactoryBean 新建springboot项目entityManagerFactory报错 解决办法 1.查看注解引入是否正确,实体类和jpa的. 2.检查

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

    目录 简介方案对比 枚举用法示例 建表 Entity Enum Controller Service Mapper 测试 1.正常操作 2.前端传空字符串 3.前端传null 简介方案对比 本处列举表示类型或状态的常用方法的对比. 法1:使用数字表示(不推荐) //1:支付宝支付:2:微信支付:3:银行卡支付 private Integer payType; 这种方法的缺点:可读性极差,排查问题也麻烦.比如:前端页面上看到了2这个类型,还要看接口文档或者问后端这是什么意思,浪费时间! 法2:使用

  • java中枚举的详细使用介绍

    枚举特点 1.用enum定义枚举类默认继承了java.lang.Enum类而不是继承了Object类.其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口 2.枚举类的构造函数只能使用private访问修饰符,如果省略了其构造器的访问控制符,则默认使用private修饰: 3.枚举类的所有实例必须在枚举类中显式列出,否则这个枚举类将永远都不能产生实例.列出这些实例时,系统会自动添加public static fin

  • Java中枚举类型的一种使用方式

    今天改同事的代码发现同事的代码中有大量的if else语句.很不美观而且可读性太差. 因为需要给前端一个key,value的列表.这个列表写死.然而同事的代码. 放几张图,大家自己感受.我都不知道以后这个api咋维护,新增一个工站,减少一个工站. 果然新的任务新增4个工站,好吧,开始给代码装扮一下. 首先,写一个枚举类. package com.smartflow.common.enumpackage; /** * @author :tao * @date :Created in 2020/8/

  • TypeScript中枚举类型的理解与应用场景

    目录 一.是什么 二.使用 数字枚举 字符串枚举 异构枚举 本质 三.应用场景 总结 一.是什么 枚举是一个被命名的整型常数的集合,用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型 通俗来说,枚举就是一个对象的所有可能取值的集合 在日常生活中也很常见,例如表示星期的SUNDAY.MONDAY.TUESDAY.WEDNESDAY.THURSDAY.FRIDAY.SATURDAY就可以看成是一个枚举 枚举的说明与结构和联合相似,其形式为: enum 枚举名{     标识

  • C++ 中的类型详细

    目录 一.初始化与赋值 二. 类型概述 三.类型分类 1.数值类型 2.void类型 四.字面值及其类型 五.变量及其类型 六.复合类型 1.指针:一种间接类型: 2.引用 七.常量类型 八.类型别名 九.类型自动推导 十.域与对象声明周期 1.思考下下面关于指针的两行代码的含义 2.经过指针的思考后,我们看看关于引用的思考 3.经过了指针和引用的思考 4.思考以下代码中&x是什么数据类型? 5.思考下面函数传参的区别? 6.下面常量表示底层常量还是顶层常量? 7.下面auto&自动推导出

  • Java中枚举的实现原理介绍

    目录 基本概述 使用方式 条件选择 循环遍历 集合映射 常用方法 总结 基本概述 在 JDK1.5 之前,通过定义常量使用的都是:public static fianl.而枚举的设计,就是把相关的常量分组到一个枚举类型里,方便创建和管理. 比如我们要定义一个颜色常量: public enum Colour { RED, YELLOW, BLUE, GREEN } 这段代码通过底层编译后,实际创建了4个枚举对象: new Enum<EnumTest>("RED", 0); n

  • java中的枚举类型详细介绍

    枚举中有values方法用于按照枚举定义的顺序生成一个数组,可以用来历遍.我们自定义的枚举类都是继承自java.lang.Enum,拥有一下实例中的功能: 复制代码 代码如下: //: enumerated/EnumClass.java // Capabilities of the Enum class import static net.mindview.util.Print.*; enum Shrubbery { GROUND, CRAWLING, HANGING } public clas

  • 深入解析Swift编程中枚举类型的相关使用

    枚举是由用户定义的数据类型的一组相关值.关键字 enum 用来定义枚举数据类型. 枚举功能 枚举在 swift 也类似于 C 和 Objective C 中结构类型 它是在一个类中声明,其值是通过该类的实例来访问 初始成员值是用枚举初始化定义的 其功能也扩展确保标准的协议功能 语法 枚举引入 enum 关键字和一对大括号内将它们定义: 复制代码 代码如下: enum enumname {    // enumeration values are described here } 例如,可以为星期

  • C#编程中枚举类型的使用教程

    枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法.例如,假设您必须定义一个变量,该变量的值表示一周中的一天.该变量只能存储七个有意义的值.若要定义这些值,可以使用枚举类型.枚举类型是使用 enum关键字声明的. enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; enum Months : byte { Jan, Feb, Mar, Apr, May, Jun,

  • 浅析Java编程中枚举类型的定义与使用

    定义枚举类型时本质上就是在定义一个类,只不过很多细节由编译器帮您补齐了,所以某些程度上,enum关键字的 作用就像是class或interface. 当您使用"enum"定义枚举类型时,实质上您定义出来的类型继承自 java.lang.Enum 类,而每个枚举的成员其实就是您定义的枚举类型的一个实例(Instance),它们都被默认为 final,所以您无法改变它们,它们也是 static 成员,所以您可以透过类型名称直接使用它们,当然最重要的,它们都 是公开的(public). 举个

随机推荐