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
0
投稿
猜你喜欢
- 命令模式定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。何时使用命令模式?当需要将发出请求的对象和执行请求
- 面试题1:说一下抽象类和接口有哪些区别?正经回答:抽象类和接口的主要区别:从设计层面来说,抽象类是对类的抽象,是一种模板设计;接口是行为的抽
- 本文实例为大家分享了iOS新浪微博分享功能的具体代码,供大家参考,具体内容如下做新浪分享 需先去http://open.weibo.com/
- 作者:京东零售 张宾1.背景在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不
- URL(Uniform Resource Locator)是统一资源 * ,它是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,
- 前言 因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没
- public static String toUtf8String(String s) {
- 右击有main方法的类===> Run as===> Run Configurations ===>双击java
- 一、概述我们对于这个图片肯定会非常熟悉,这两幅图片我们都可以看做是一个文件结构,对于这样的结构我们称之为树形结构。在数据结构中我们了解到可以
- 参考答案java.sql.Date 是 java.util.Date 的子类java.util.Date 是 JDK 中的日期类,精确到时、
- Java语言是SUN(Stanford University Network,斯坦福大学网络公司)公司1995年推出的一门高级编程语言,起初
- 前言LocalDateTime、LocalDate、LocalTime 是 Java8 全新的日期框架,加强了对时间的管理,有很多特别好用的
- 这个例子需要使用google的开源项目zxing的核心jar包core-3.2.0.jar可以百度搜索下载jar文件,也可使用maven添加
- 在我们日常开发过程中,通常会涉及到数据权限问题,下面以我们常见的一种场景举例:一个公司有很多部门,每个人所处的部门和角色也不同,所以数据权限
- 概述日常工作中,我们经常会有发送 HTTP 网络请求的需求,概括下我们常见的发送 HTTP 请求的需求内容:可以发送基本的 GET/POST
- 一、SpringBoot整合FastJson1.1、引入FastJson依赖包maven项目:<dependency> &nbs
- 1.准备工作第一步就是先要注册一个支付宝的账号(注册这里不说,不是重点),然后登入官方首页,去到应用列表里面找到沙箱应用。基本信息的APPI
- 一、synchronized 有不足新事物的出现要不是替代老事物,要么就是对老事物的补充JUC 的 locks 就是对 synchroniz
- 本文实例讲述了Java获得当前时间前指定几个小时具体时间的方法。分享给大家供大家参考,具体如下:package getBeforeHourD
- 前言Java虽然五脏俱全但总有软肋,譬如获取CPU等硬件信息,当然我们可以通过JNI调用C/C++来获取,但对于对C/C++和Windows