Springboot JPA 枚举Enum类型存入到数据库的操作
作者:miskss 发布时间:2023-11-25 16:11:40
标签:Springboot,JPA,枚举,数据库
1、使用JPA 的@Enumerated 注解 ,可以直接将Enum映射到数据库中。
但是value的值只有两种方式选择,一种是使用枚举的序号映射,一种是枚举的名称来映射。
public enum EnumType {
/** Persist enumerated type property or field as an integer. */
ORDINAL,
/** Persist enumerated type property or field as a string. */
STRING
}
如果想存入枚举中的自定义的值,则需要实现AttributeConverter接口
2、实现AttributeConverter接口方式
/**
* @param <DB> : 保存到数据库的数据类型
* @author peter
* date: 2019-05-15 16:57
**/
public interface PersistEnum2DB<DB> {
DB getData();
}
import javax.persistence.AttributeConverter;
/**
* @param <ATTR> 实体类中枚举的类型,需实现{@link PersistEnum2DB} 接口
* @param <DB> 保存到数据库的数据类型
* @author peter
* date: 2019-05-15 16:59
*/
public abstract class AbstractEnumConverter<ATTR extends Enum<ATTR> & PersistEnum2DB<DB>, DB> implements AttributeConverter<ATTR, DB> {
private final Class<ATTR> clazz;
public AbstractEnumConverter(Class<ATTR> clazz) {
this.clazz = clazz;
}
@Override
public DB convertToDatabaseColumn(ATTR attribute) {
return attribute != null ? attribute.getData() : null;
}
@Override
public ATTR convertToEntityAttribute(DB dbData) {
if (dbData == null) return null;
ATTR[] enums = clazz.getEnumConstants();
for (ATTR e : enums) {
if (e.getData().equals(dbData)) {
return e;
}
}
throw new UnsupportedOperationException("枚举转化异常。枚举【" + clazz.getSimpleName() + "】,数据库库中的值为:【" + dbData + "】");
}
}
使用方式
import com.tourcoo.parking.enums.convert2db.AbstractEnumConverter;
import com.tourcoo.parking.enums.convert2db.PersistEnum2DB;
/**
* @author peter
* create: 2019-05-15 14:33
**/
public enum PayStatus implements PersistEnum2DB<Integer> {
NONPAY(0, "未支付"),
PAID(1, "已支付");
private int code;
private String msg;
PayStatus(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
@Override
public Integer getData() {
return code;
}
public static class Converter extends AbstractEnumConverter<PayStatus, Integer> {
public Converter() {
super(PayStatus.class);
}
}
}
//支付状态
@Convert(converter = PayStatus.Converter.class)
private PayStatus payStatus;
补充: SpringBoot | Jpa 将Java枚举映射为基本值类型
解决方法之一:
使用实体属性类型转换器AttributeConverter
场景假设:
在代码中使用枚举类来映射用户性别(如下代码所示),在数据库中使用字符映射性别(M ,F),Hibernate提供了AttributeConverter解决上述场景的转换问题
public enum Gender {
MALE( 'M' ),
FEMALE( 'F' );
private final char code;
Gender(char code) {
this.code = code;
}
public static Gender fromCode(char code) {
if ( code == 'M' || code == 'm' ) {
return MALE;
}
if ( code == 'F' || code == 'f' ) {
return FEMALE;
}
throw new UnsupportedOperationException(
"The code " + code + " is not supported!"
);
}
public char getCode() {
return code;
}
}
User实体类定义如下,重点在 @Convert(converter = GenderConverter.class)注释
@Entity
@Data
@ToString
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@Convert(converter = GenderConverter.class)
private Gender gender;
}
定义一个GenderConverter的类,需要实现AttributeConverter接口,实现convertToDatabaseColumn和convertToEntityAttribute,作用是分别封装从实体类映射至数据库字段数值的逻辑和从数据库字段数值映射到代码实体类中的枚举类值。
public class GenderConverter implements AttributeConverter<Gender,Character> {
@Override
public Character convertToDatabaseColumn(Gender gender) {
if ( gender == null ) {
return null;
}
return gender.getCode();
}
@Override
public Gender convertToEntityAttribute(Character value) {
if ( value == null ) {
return null;
}
return Gender.fromCode( value );
}
}
测试
@SpringBootTest
@Slf4j
public class AttributeConverterTest {
@Resource
private UserRepository userRepository;
@Test
void should_user__when__give_user() {
//given
User user1 = new User(null,"Janny", Gender.FEMALE);
User user2 = new User(null,"Tom", Gender.MALE);
//when
User actUser1 = userRepository.save(user1);
User actUser2 = userRepository.save(user2);
//then
Assertions.assertNotNull(actUser1);
Assertions.assertNotNull(actUser2);
}
}
例外Hibernate也提供其他的方法,如使用@Enumerated注解,详情可阅读这篇文档
来源:https://blog.csdn.net/wanping321/article/details/90269057


猜你喜欢
- 本文基于jdk1.8进行分析关于HashMap的简介,可以参考这篇文章https://www.jb51.net/article/154177
- 目录概述ClassPoolCtClassCtMthodCtFieldCtConstructorClassPathClassLoader示例创
- Android 捕获运行时异常详解Android 异常分为两类:CheckedException 和 UnCheckedExceptionC
- 原理解析在开发当中,“断点续传”这种功能很实用和常见,听上去也是比较有“逼格”的感觉。所以通常我们都有兴趣去研究研究这种功能是如何实现的?
- 这篇文章主要介绍发送验证码和校验验证码的功能,用到一个第三方平台Bmob,那Bmob是什么呢?Bmob可以开发一个云存储的移动应
- 利用apache ftp工具实现文件的上传下载和删除,具体如下1、下载相应的jar包 com
- 判断对象存活方法引用计数法:在对象中添加一个引用计数子,每当一个地方引用他时,计数器就加一,当引用失效时,计数器就减一。会有对象循环引用问题
- 不过在实际的工作中,很少会直接用到它。通常都是用的spring-quartz组件,直接通过配置,让spring框架来自动装配如下就是spri
- 1、Android内存管理机制1.1 Java内存分配模型先上一张JVM将内存划分区域的图程序计数器:存储当前线程执行目标方法执行到第几行。
- 最近由于参加一个小小的创意比赛,用安卓做了一个小小的图片识别应用,主要是通过拍照识别图片中的菜品,还有对象位置查找的东西。之前没有做过安卓,
- 1.先通过程序生成报表样式的HTML页面,然后修改HTML页面的后缀名为DOC。 2.定制WORD文档的模板文件,在C#中操作WORD模板,
- 接着上一篇再为大家介绍java应用和输入输出常用方法,供大家参考,具体内容如下一、应用1、使用StringBuilder或StringBuf
- 本文实例讲述了Java使用Socket通信传输文件的方法。分享给大家供大家参考,具体如下:前面几篇文章介绍了使用Java的Socket编程和
- 一.抽象类(一)概念 在继承的层次结构中,每个新的子类都使类变得更加明确和具体。如果从一个子类向父类
- 悲观锁、乐观锁简介: 悲观锁:同步操作。即用户A在操作某条数据时,为其上锁,限制其他用户操作,用户A操作完成提交事务后其他用户方可
- 前言在我们公司里,不同的服务之间通过Feign进行远程调用,但是,我们在尝试使调用可重试时遇到了一个小问题,Feign框架本身可以配置的自己
- Tab与TabHost:这就是Tab,而盛放Tab的容器就是TabHost 。如何实现?? 每一个Tab还对应了一个布局,这个就有点好玩了。
- 本文实例为大家分享了SSM实现学生管理系统的具体代码,供大家参考,具体内容如下概述基于Spring + Spring MVC 的学生管理系统
- 导入后gradle building 一直到跑,卡住了,一般是gradle没有下载,又下不下来的原因。去 http://serv
- 前言最近断断续续地把项目的界面部分的代码由JAva改成了Kotlin编写,并且如果应用了kotlin-android-extensions插