java开发 - 枚举类型自定义转换 - 自定义序列化/反序列化,mybatis/jpa字段转换
项目牵扯到了jpa和mybatis,枚举映射的值类型有字符串,数值,自定义信息,所以统一了一下规则,方便开发,反正我觉得很好用。
·
描述
项目牵扯到了jpa和mybatis,枚举映射的值类型有字符串,数值,自定义信息,所以统一了一下规则,方便开发,反正我觉得很好用
举例
enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
字符串可以使用
@Enumerated(EnumType.STRING)
这个是按照枚举的枚举值的名称进行存储
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
数值可以使用
@Enumerated(EnumType.ORDINAL)
这个是按照枚举的枚举值的次序进行存储
0,1,2,3,4,5,6
如果我想存储的时候SUNDAY代表的是0, 那么就要改变顺序,如果已经上线了,就可能带来很大的风险
实战
//枚举类字段的使用
/**
* 星期 1.星期一 2.星期二 3.星期三 4.星期四 5.星期五 6.星期六 7.星期日
*/
@ApiModelProperty("星期 1.星期一 2.星期二 3.星期三 4.星期四 5.星期五 6.星期六 7.星期日")
//mybatis-plus字段映射 ,@Result字段映射
@TableField(value = "weekday", typeHandler = Weekday.WeekdayConverter.class)
//反序列化的场景是前端传值时可以自定义使用
@JsonDeserialize(using = Weekday.WeekdayJsonDeserializer.class)
//序列化为枚举继承的泛型类型值, 例如:redis缓存,json相应数据等
@JsonSerialize(using = EnumConstant.EnumJsonSerializer.class)
//jpa框架字段映射
@Convert(converter = Weekday.WeekdayConverter.class)
//jpa字段映射信息
@Column(name = "weekday", columnDefinition = "tinyint NOT NULL DEFAULT 1 COMMENT '星期 1.星期一 2.星期二 3.星期三 4.星期四 5.星期五 6.星期六 7.星期日'")
private Weekday weekday;
//枚举类
public enum Weekday implements EnumConstant<Integer> {
//星期一
MONDAY(1, 1, "星期一", "悲催的周一"),
//星期二
TUESDAY(2, 2, "星期二", "周二我爱摸鱼"),
//星期三
WEDNESDAY(3, 3, "星期三", "调休去看电影"),
//星期四
THURSDAY(4, 4, "星期四", "期待中度过"),
//星期五
FRIDAY(5, 5, "星期五", "哼着欢快的小曲"),
//星期六
SATURDAY(6, 6, "星期六", "加班吐血中"),
//星期日,
//注意这里的类型值是0
SUNDAY(0, 7, "星期日", "吸血鬼继续压榨");
Weekday(Integer typeValue, Integer value, String name, String showInfo) {
this.typeValue = typeValue;
this.value = value;
this.name = name;
this.showInfo = showInfo;
}
/**
* 类型值,没想好怎么用,保留
*/
private final Integer typeValue;
/**
* 枚举值
*/
private final Integer value;
/**
* 枚举名称
*/
private final String name;
/**
* 展示信息
*/
private final String showInfo;
/**
* 获取默认值
* 如果需要就返回,不需要就不返回
*
* @return 这里返回的默认的周一
*/
@Override
public Integer getDefaultValue() {
return MONDAY.getValue();
}
/**
* 获取枚举值
*
* @return 枚举值
*/
@Override
public Integer getValue() {
return this.value;
}
/**
* 获取枚举名称
*
* @return 名称
*/
@Override
public String getName() {
return this.name;
}
/**
* 获取枚举展示信息
* 可以在导出报表的时候作为直接展示使用,或者是返回给前端直接使用
* 这个方法复写了父类
*
* @return 展示信息
*/
@Override
public String getExportShowValue() {
return this.showInfo;
}
/**
* mybatis与jpa框架数据库枚举字段转换
* 如果没有使用到相应的框架, 可以把相应的继承或实现的代码删除
* 如果不使用jpa框架,@Converter可以不写
*/
public static class WeekdayConverter extends AbstractEnumConverter<Weekday, Integer> {
}
/**
* 自定义json反序列化
*/
public static class WeekdayJsonDeserializer extends EnumJsonDeserializer<EnumConstant<Integer>, Integer> {
@Override
public Weekday deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
ObjectCodec codec = p.getCodec();
String value = codec.readValue(p, String.class);
Weekday[] enumConstants = Weekday.values();
for (Weekday enumConstant : enumConstants) {
//这里使用显示信息反序列化枚举
//例如前端传值为"哼着欢快的小曲",则为星期五,枚举值为FRIDAY
if (enumConstant.getExportShowValue().equals(value)) {
return enumConstant;
}
}
throw new IllegalArgumentException("没有找到值");
}
}
}
//继承的枚举常量信息
public interface EnumConstant<T> {
/**
* 获取默认值
*
* @return
*/
default T getDefaultValue() {
return null;
}
/**
* 获取枚举值
*
* @return 枚举值
*/
T getValue();
/**
* 获取名称
*
* @return 名称
*/
String getName();
/**
* 导出excel等的显示值
*
* @return 显示值
*/
default String getExportShowValue() {
return getName();
}
default EnumConstant<T> getDefault() {
return null;
}
/**
* 是否使用默认
*
* @return 默认否
*/
default boolean whetherUseDefault() {
return false;
}
default void setFieldValue(T value) {
}
default T getFieldValue() {
return null;
}
/**
* 根据值获取枚举
*
* @param value 值
* @return 枚举
*/
default EnumConstant<T> findByValue(T value) {
Class<? extends EnumConstant<T>> aClass = (Class<? extends EnumConstant<T>>) this.getClass();
EnumConstant<T>[] enumConstants = aClass.getEnumConstants();
if (Objects.isNull(enumConstants) || 0 == enumConstants.length) {
throw new IllegalArgumentException("没有找到值");
}
for (EnumConstant<T> enumConstant : enumConstants) {
if (enumConstant.getValue().equals(value)) {
return enumConstant;
}
}
throw new IllegalArgumentException("没有找到值");
}
/**
* mybatis框架与jpa框架枚举类型自定义转换
*/
abstract class AbstractEnumConverter<E extends EnumConstant<T>, T> extends BaseTypeHandler<EnumConstant<T>> implements AttributeConverter<EnumConstant<T>, T> {
protected Class<E> constant;
{
constant = (Class<E>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public E getDefault() {
return null;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, EnumConstant<T> parameter, JdbcType jdbcType) throws SQLException {
T value = parameter.getValue();
ps.setObject(i, value);
}
@Override
public EnumConstant<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
T columnValue = (T) rs.getObject(columnName);
return getValue(columnValue);
}
@Override
public EnumConstant<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
T columnValue = (T) rs.getObject(columnIndex);
return getValue(columnValue);
}
@Override
public EnumConstant<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
T columnValue = (T) cs.getObject(columnIndex);
return getValue(columnValue);
}
/**
* 根据值获取枚举
*
* @param columnValue 值
* @return 枚举
*/
public EnumConstant<T> getValue(T columnValue) {
EnumConstant<T>[] enumConstants = constant.getEnumConstants();
if (Objects.isNull(enumConstants) || 0 == enumConstants.length) {
throw new IllegalArgumentException("没有找到值");
}
for (EnumConstant<T> enumConstant : enumConstants) {
if (enumConstant.getValue().equals(columnValue)) {
return enumConstant;
}
}
EnumConstant<T> defaultEnum = getDefault();
if (Objects.isNull(defaultEnum)) {
throw new IllegalArgumentException("没有找到值");
}
return defaultEnum;
}
/**
* 转换枚举到数据库字段
*
* @param enumConstant the entity attribute value to be converted
* @return 存储数据
*/
@Override
public T convertToDatabaseColumn(EnumConstant<T> enumConstant) {
if (Objects.isNull(enumConstant)) {
throw new IllegalArgumentException("转换参数为空");
}
return enumConstant.getValue();
}
/**
* 转换数据为枚举
*
* @param value the data from the database column to be
* converted
* @return 枚举数据
*/
@SneakyThrows
@Override
public EnumConstant<T> convertToEntityAttribute(T value) {
return this.getValue(value);
}
}
/**
* json序列化
*/
class EnumJsonSerializer<E extends EnumConstant<T>, T> extends JsonSerializer<EnumConstant<T>> {
@Override
public void serialize(EnumConstant<T> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeObject(value.getValue());
}
}
/**
* json反序列化
*/
class EnumJsonDeserializer<E extends EnumConstant<T>, T> extends JsonDeserializer<EnumConstant<T>> {
@Override
public EnumConstant<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
ObjectCodec codec = p.getCodec();
Field field = findField(p.getCurrentName(), p.getCurrentValue().getClass());
Class<E> e = (Class<E>) field.getType();
Type[] genericInterfaces = e.getGenericInterfaces();
ParameterizedType genericInterface = (ParameterizedType) genericInterfaces[0];
Class<T> t = (Class<T>) genericInterface.getActualTypeArguments()[0];
T value = codec.readValue(p, t);
EnumConstant<T>[] enumConstants = e.getEnumConstants();
if (Objects.isNull(enumConstants) || 0 == enumConstants.length) {
throw new IllegalArgumentException("没有找到值");
}
for (EnumConstant<T> enumConstant : enumConstants) {
if (enumConstant.getValue().equals(value)) {
return enumConstant;
}
}
EnumConstant<T> defaultEnum = enumConstants[0].getDefault();
if (Objects.isNull(defaultEnum)) {
throw new IllegalArgumentException("没有找到值");
}
if (!defaultEnum.whetherUseDefault()) {
throw new IllegalArgumentException("没有找到值");
}
return defaultEnum;
}
public Field findField(String name, Class<?> c) {
for (; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (field.getName().equals(name)) {
return field;
}
}
}
return null;
}
}
}

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)