关于Jpa Entity字段转换的实现

469 阅读2分钟

我们在操作数据库,无论使用Jpa还是Mybatis,都可能遇到需要数据转换情况。例如有如下Entity:

@Entity
@Table(name = "t_person")
public class Person{
    @Id
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    // 此处Sex需要转换后才能存入数据库
    @Column(name = "sex")
    private Sex sex;
		
    @Column(name = "age")
    private int age;
	
    // ....省略setter和getter....
}

其中Sex为枚举Enum, Sex代码如下:

public enum Sex {

    MALE("男","Male"), FEMALE("女","Female");

    private String name;
    private String code;

    public Sex(String name,String code){
            this.name = name;
            this.code = code;
    }

    public String getName(){ return name; }

    public String getCode(){ return code; }

    public Sex getByCode(String code){
            return code == null ? null : valueOf(code);
    }
}

此时,我们保存Person时,Sex字段只需要保存Sex枚举中的code值。查询时,也需要将查询出的sex字符串转换为Sex枚举值。如果不做任何出来,Jpa默认会以枚举角标方式储存,例如sex = FEMALE,存入数据库的值将为1。所以我们需要用AttributeConverter做一些转换,转换实现如下:

@Converter(autoApply = true)
public class SexConverter implements AttributeConverter<Sex, String> {
    /**
     * 将Sex枚举,转换成字符串,保存入数据库
     */
    @Override
    public String convertToDatabaseColumn(Sex sex) {
        if (sex == null) {
            return null;
        }
        return sex.getCode(); 
    }

    /**
     * 将数据库查询出的值,转换为Sex枚举
     */
    @Override
    public Sex convertToEntityAttribute(String code) {
        if (code == null) {
            return null;
        }
        return Sex.getByCode(code);
    }
}

此时若sex = FEMALE,存入数据库的值将为Female,此方式为Jpa 2.1提供的装换实现, 在Jpa 2.0时,也有@Enumerated注解来使用注解保存解析的方式,代码如下(注意sex变量的注解):

@Entity
@Table(name = "t_person")
public class Person{
    @Id
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    // 此处Sex需要转换后才能存入数据库
    @Column(name = "sex")
    @Enumerated(EnumType.STRING) 
    private Sex sex;

    @Column(name = "age")
    private int age;

    // ....省略setter和getter....
}

其中,EnumType有【ORDINAL、STRING】两个值

  • ORDINAL :按照枚举的下标来存储(即:enum.ordinal()的值),例如sex = FEMALE,存入数据库的值将为1,Jpa在枚举类型无任何处理时,默认是使用这种方式存储。
  • STRING :按照枚举的名字存储(即:enum.name()的值),例如sex = FEMALE,存入数据库的值将为:FEMALE。

学习时,注意到还有一个@MapKeyEnumerated注解暂时未使用过,使用熟悉后再写上。