我们在操作数据库,无论使用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注解暂时未使用过,使用熟悉后再写上。