首页 > 技术文章 > 枚举保存到数据库中为序号解决方案

GoslingWu 2020-09-18 12:02 原文

普通枚举转换配置

枚举类

package com.gecko.charging.partner.enums;

import com.alibaba.fastjson.annotation.JSONType;
import com.gecko.charging.common.BaseEnum;
import com.gecko.charging.util.json.EnumDeserializer;
import com.gecko.charging.util.json.EnumSerializer;

/**
 * 合作商类型
 */
//@JSONType(serializer = EnumSerializer.class, deserializer = EnumDeserializer.class, serializeEnumAsJavaBean = true)
public enum PartnerType implements BaseEnum {
    agent(1),//代理商
    purchaser(2),//采购商
    operators(3),//运营商
    ;

    private Integer code;

    PartnerType(Integer code) {
        this.code = code;
    }

    @Override
    public Integer getCode() {
        return this.code;
    }
}

枚举转换类 @Converter(autoApply = true)自动适应

package com.gecko.charging.partner.enums.converter;

import com.gecko.charging.device.enums.DeviceExceptionStatus;
import com.gecko.charging.partner.enums.PartnerType;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Objects;

/**
* @description: 合作商Converter
* @author: Wzq
* @create: 2020-03-02 14:33
*/
@Converter(autoApply = true)
public class PartnerTypeConverter implements AttributeConverter<PartnerType, Integer> {

   @Override
   public Integer convertToDatabaseColumn(PartnerType attribute) {
       return attribute.getCode();
   }

   @Override
   public PartnerType convertToEntityAttribute(Integer dbData) {
       for (PartnerType e : PartnerType.values()) {
           if (Objects.equals(e.getCode(), dbData)) return e;
       }
       return null;
   }

}

在实体类中使用

package com.gecko.charging.partner.entity;

import com.gecko.charging.partner.enums.PartnerType;
import com.gecko.charging.partner.enums.PartnerSettlementMethod;
import com.meenoframework.common.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Table;
import java.util.Date;

/**
 * @description: 合作商
 * @author: Wzq
 * @create: 2020-03-02 14:25
 */
@Entity
@Table(name = "partner")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Partner extends BaseEntity {

    // 用户id
    private Long userId;

    // 邮箱
    private String email;

    // 公司名称
    private String companyName;

    // 组织机构代码
    private String orgCode;

    //区域id
    private String areaId;

    //详细地址
    @Column(columnDefinition = "TEXT")
    private String address;

    //合作商类型
    @Column(name = "type")
    private PartnerType partnerType;

    //结算方式
    private PartnerSettlementMethod settlementMethod;

    // 营业执照
    private String businessLicense;

    // 小区名称
    private String areaName;

    // 创建时间
    @CreatedDate
    private Date createTime;

    // 创建id
    @CreatedBy
    private Long creatorId;

    // 修改人
    @LastModifiedBy
    private Long updateId;

    // 修改时间
    @LastModifiedDate
    private Date updateTime;

    // 是否删除
    private Integer isDeleted;

}

高级适配玩法,上面那种方法需要一个枚举对应一个转换类很麻烦

基础枚举转换类

package com.gecko.charging.common.jpaenum.converter;

import com.gecko.charging.common.BaseEnum;

import javax.persistence.AttributeConverter;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

public class BaseEnumConverter <X extends BaseEnum<Y>, Y> implements AttributeConverter<BaseEnum<Y>, Y> {

    private Class<X> xclazz;
    private Method valuesMethod;

    @SuppressWarnings("unchecked")
    public BaseEnumConverter() {
        this.xclazz = (Class<X>) (((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments())[0];
        try {
            valuesMethod = xclazz.getMethod("values");
        } catch (Exception e) {
            throw new RuntimeException("can't get values method from " + xclazz);
        }
    }

    @Override
    public Y convertToDatabaseColumn(BaseEnum attribute) {
        return attribute == null ? null : (Y) attribute.getCode();
    }

    @SuppressWarnings("unchecked")
    @Override
    public X convertToEntityAttribute(Y dbData) {
        try {
            X[] values = (X[]) valuesMethod.invoke(null);
            for (X x : values) {
                if (x.getCode().equals(dbData)) {
                    return x;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("can't convertToEntityAttribute" + e.getMessage());
        }
        throw new RuntimeException("unknown dbData " + dbData);
    }
}


枚举基础类

package com.gecko.charging.common;

public interface BaseEnum<Y> {
    Y getCode();

    static BaseEnum[] getValues() {
        return new BaseEnum[0];
    }
}

枚举

package com.gecko.charging.device.enums;


import com.alibaba.fastjson.annotation.JSONType;
import com.gecko.charging.common.BaseEnum;
import com.gecko.charging.util.json.EnumDeserializer;
import com.gecko.charging.util.json.EnumSerializer;

/**
 * 设备归属枚举
 */
@JSONType(serializer = EnumSerializer.class, deserializer = EnumDeserializer.class, serializeEnumAsJavaBean = true)
public enum DeviceOwnerType implements BaseEnum<Integer> {
    PLATFORM(1),// 平台
    PROPERTY(2),// 物业商
    FRANCHISEE(3),// 加盟商
    ;

    private Integer code;

    DeviceOwnerType(Integer code) {
        this.code = code;
    }

    @Override
    public Integer getCode() {
        return code;
    }

        public static class Convert extends BaseEnumConverter<DeviceOwnerType, Integer> {

      }
}

实体类 需要加注解 @Convert(converter = DeviceOwnerType.Convert.class)

package com.gecko.charging.device.entity;


import com.gecko.charging.device.enums.*;
import com.meenoframework.common.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.util.Date;

/**
 * 充电设备
 * @Author: JeffGao
 * @Date: Created in 2020/2/24
 * @Description:
 */
@Entity
@Table(name = "charging_device")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class ChargingDevice extends BaseEntity {

  // 归属类型
  @Column(columnDefinition = "TINYINT")
  @Convert(converter = DeviceOwnerType.Convert.class)
  private DeviceOwnerType ownerType;
  // 归属者ID
  private Long ownerId;
  // 分润类型
  @Column(columnDefinition = "TINYINT")
  private ProfitShareType profitShareType;
  // 场景类型
  @Column(columnDefinition = "TINYINT")
  private SceneType sceneType;
  // 设备类型
  @Column(columnDefinition = "TINYINT")
  private DeviceType type;
  // 省市区编号
  private String areaId;
  // 纬度
  private String lat;
  // 经度
  private String lon;
  // sn号
  private String sn;
  // sn名称
  private String snName;
  // 插座数
  private Integer plugBaseCount;
  // 设备状态
  @Column(columnDefinition = "TINYINT")
  private DeviceStatus status;
  // 断电功率
  private Integer cutPower;
  // 收费套餐
  private Long feePackId;
  // 详细地址
  private String address;
  // 创建人
  private Long creatorId;
  @CreatedDate
  private Date createTime;
  @LastModifiedDate
  private Date updateTime;
  // 上线时间
  private Date onlineTime;

}

@Convert(converter = DeviceOwnerType.Convert.class)
使用这个注解配置生效!

推荐阅读