• 在spring data jpa中使用自定义转换器之使用枚举转换


    转载请注明http://www.cnblogs.com/majianming/p/8553217.html

    在项目中,经常会出现这样的情况,一个实体的字段名是枚举类型的

    我们在把它存放到数据库中是需要将其映射为字符串或者其他类型

     1  public enum Color{
     2     
     3         RED(1, "RED"),
     4         ORANGE(2, "ORANGE");
     5 
     6         private Integer rainbowIndex;//在彩虹中的序号
     7         private String name;
     8 
     9         Type(Integer rainbowIndex, String name) {
    10             this.rainbowIndex= rainbowIndex;
    11             this.name= name;
    12         }
    13 
    14         public Integer getRainbowIndex() {
    15             return rainbowIndex;
    16         }
    17 
    18         public String getName() {
    19             return name;
    20         }
    21
    22 public static Type getTypeFromName(String name){ 23 for (Type type : Type.values()) { 24 if (type.getName().equals(name)){ 25 return type; 26 } 27 } 28 return null; 29 } 30 }
    @Entity
    @Table(name = "tb_paper")
    public class Paper {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long no;
    
        private Color color;
    
        public Long getNo() {
            return no;
        }
    
        public void setNo(Long no) {
            this.no= no;
        }
        public Color getColor() {
            return type;
        }
    
        public void setColor(Color type) {
            this.type = type;
        }
    
    
    }

    如果这样直接写,会怎样?

    在保存到数据库时没有错误信息,它帮我们生成一张表,而且还把其中一个字段rainbowIndex映射到了数据表tb_paper上的color字段(从参数类型上可以看出),

    CREATE TABLE `tb_paper` (
      `no` bigint(20) NOT NULL AUTO_INCREMENT,
      `color` int(11) DEFAULT NULL,
      PRIMARY KEY (`no`)
    ) DEFAULT CHARSET=utf8;

    那我两个参数在实体中都是String类型的,框架会帮我如何选择?

     1  public enum Color{
     2     
     3         RED("1", "RED"),
     4         ORANGE("2", "ORANGE");
     5 
     6         private String rainbowIndex;//在彩虹中的序号 我们这里改成String类型 虽然使用数值类型比较恰当
     7         private String name;
     8 
     9         Type(String rainbowIndex, String name) {
    10             this.rainbowIndex= rainbowIndex;
    11             this.name= name;
    12         }
    13 
    14         public String getRainbowIndex() {
    15             return rainbowIndex;
    16         }
    17 
    18         public String getName() {
    19             return name;
    20         }
    21
    22 public static Type getTypeFromName(String name){ 23 for (Type type : Type.values()) { 24 if (type.getName().equals(name)){ 25 return type; 26 } 27 } 28 return null; 29 } 30 }

    发现数据库还是 `color` int(11) DEFAULT NULL ,这就肯定不对了

    那么这里出现了两个问题

    1. 映射的类型错误
    2. 映射的字段不能指定

    我们使用jpa2.1规范里面的属性转换器

     1 @Converter(autoApply = true)
     2 public class ColorConverter implements AttributeConverter<Color, String> {//泛型指的是你在实体用的类型,第二个是指需要映射到数据库的类型对应的java中的类型
     3 
     4     @Override
     5     public String convertToDatabaseColumn(Color attribute) {
     6         return attribute.getName();
     7     }
     8 
     9     @Override
    10     public Color convertToEntityAttribute(String dbData) {
    11         return Color.getColorFromName(dbData);
    12     }
    13 }

    看下数据库表 `color` varchar(255) DEFAULT NULL ,字段映射对了,需要注意的是如果上面注解@Converter的没有(autoApply = true),(默认)表示在所有用到Color类型的实体映射是将默认映射为Integer类型,其实就是不生效,如果需要全局生效,加上(autoApply = true)就可以了,如果需要对于一个实体的一个属性单独处理的话,在需要的属性加上@Convert(converter = ColorConverter.class)


    参考

      http://hantsy.blogspot.com/2013/12/jpa-21-attribute-converter.html

      https://www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/


    转载请注明http://www.cnblogs.com/majianming/p/8553217.html

  • 相关阅读:
    CSS3 flex 布局 图片撑大 父级元素被放大 解决办法
    CentOS 下使用 cron crond crontab 执行定时任务
    Linux 安装 pcre
    Nginx 下载编译安装
    油猴脚本编写教程
    用图形来表达你的意思
    免费绘图软件drawio.io快捷键说明
    centos/Mac 下的多线程下载工具 axel
    巧用对象,生成不重复随机数
    mac 下 Redis5 BloomFilter 安装及与 python连用
  • 原文地址:https://www.cnblogs.com/majianming/p/8553217.html
Copyright © 2020-2023  润新知