5.4.3.2 标注枚举类型@Enumerated

本文介绍如何在实体类中使用@Enumerated注解处理枚举类型,并探讨枚举类型的存储方式选择及其影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实体Entity中通过@Enumerated标注枚举类型,例如将CustomerEO实体中增加一个CustomerType类型的枚举型属性,标注实体后的代码如下所示。

@Entity

@Table(name = "customer")

public class CustomerEO implements java.io.Serializable {

……

         private CustomerType type;

 

         @Enumerated(EnumType.STRING)

         public CustomerType getType() {

                   return type;

         }

 

         public void setType(CustomerType type) {

                   this.type = type;

         }

 

         public enum CustomerType {

                   COMPETITOR, INVESTOR, PARTNER, VENDER

         }

 

}

在实体中虽然标注成枚举类型,但当实体持久化后,表中所对应的值仍旧是基本的数据类型,以上代码创建表的SQL语句是:

CREATE TABLE customer (

         id int(20) NOT NULL auto_increment,

         name varchar(255),

         type varchar(255),

         PRIMARY KEY (id)

)

使用枚举类型后,在创建实体时便可以直接引用枚举类型,例如以下代码所示。

CustomerEO customer = new CustomerEO();

customer.setName("Janet2");

customer.setType(CustomerType.PARTNER);

entityManager.persist(customer);

在使用@Enumerated注释时,需要注意以下几个问题:

l         因为枚举类型的有名称和值两个属性,所以在持久化时可以选择持久化名称或是持久化值。通过EnumType来定义,它有两个值如下所示。

public enum EnumType {

ORDINAL,

STRING

}

ORDINAL表示持久化的为枚举类型的值,STRING表示持久化的为枚举类型的名称。默认为ORDINAL,持久化值。例如以上示例中标注的为STRING,这样持久化实体后,数据库中保存的是枚举类型的名称,如图所示。

若此时改成ORDINAL,代码如下:

         @Enumerated(EnumType.ORDINAL)

         public CustomerType getType() {

                   return type;

         }

则同样持久化的实体后,数据库保存的结果如图所示。

l         如何选择STRINGORDINAL

如果使用STRING保存,虽然从数据库中查询数据时非常直观,能够清楚的看出该类型代表意义,但这样也会带来其他的问题。若此时枚举类型的定义改变,例如上例中的枚举类型名称改为:

         public enum CustomerType {

                   CUST_COMPETITOR, INVESTOR, PARTNER, VENDER

         }

则此时数据库中保存的“COMPETITOR”的值将不能转化为枚举类型CustomerType中的“CUST_COMPETITOR”的值。但若使用ORDINAL则不会带来这种问题。所以建议使用ORDINAL类型来持久化枚举类型。

l         枚举类型的定义位置,实体外部VS实体内部。

上例中CustomerType枚举类型定义在CustomerEO实体内部,这是因为只有CustomerEO这个实体会使用CustomerType类型,其他的实体不会使用该类型。该类型与这个实体关系紧密联系。

但若此时多个实体公用一个枚举类型时,则可以将枚举类型单独定义,定义在实体的外部。有这样一个枚举类型BusinessLine,它定义在实体外部,代码如下:

public enum BusinessLine {

         REAL_ESTATE,FINANCE, NON_PROFIT

}

例如CustomerEO实体增加一个BusinessLine的枚举类型,代码如下所示。

@Entity

@Table(name = "customer")

public class CustomerEO implements java.io.Serializable {

……

         private BusinessLine businessLine;

 

         @Enumerated(EnumType.STRING)

         public BusinessLine getBusinessLine() {

                   return businessLine;

         }

 

         public void setBusinessLine(BusinessLine businessLine) {

                   this.businessLine = businessLine;

         }

}

现在这三个部分的代码是 package com.example.club.entity; public enum Status { PENDING, APPROVED,SUSPENDED,REJECTED } package com.example.club.util; import com.example.club.entity.Role; import com.example.club.entity.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.Collections; public class CustomUserDetails implements UserDetails { private final User user; public CustomUserDetails(User user) { this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return Collections.singletonList( new SimpleGrantedAuthority("ROLE_" + user.getRole().name()) ); } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return user.getStatus() == Status.APPROVED; } public User getUser() { return user; } } package com.example.club.entity; import lombok.Data; import javax.persistence.*; import java.util.List; @Entity @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false) private String password; @Column(nullable = false) private String email; private String realName; private String profilePic; @Enumerated(EnumType.STRING) private Role role; @Enumerated(EnumType.STRING) private Status status; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Blog> blogs; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Friendship> friendships; @OneToMany(mappedBy = "friend", cascade = CascadeType.ALL, orphanRemoval = true) private List<Friendship> friendOf; }
最新发布
06-25
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值