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://docs.jboss.org/hibernate/stable/orm/userguide/html_single/Hibernate_User_Guide.html