Orika 枚举 属性自定义映射

656 阅读1分钟

Orika官网

需求,数据库对象和DTO等等各种O对象转换,数据库对象使用枚举类,各种O使用的Integer

1. 接口

/**
 * 2022/3/16
 * 用于枚举转换
 *
 * @author Junisyoan
 */
public interface IBaseEnum {
    int getValue();
}

2. 需要的对象

@Getter
public enum UserTypeEnum implements IBaseEnum{
    /**
     * 游客
     */
    VISITOR(1),
    /**
     * 普通用户
     */
    COMMON_USER(2),
    
    // 很多用户类型...
    ;

    UserTypeEnum(Integer value) {
        this.value = value;
    }

    private final Integer value;
}
/**
 * 实体对象
 */
@Setter
@Getter
public class ClientUser {

    /**
     * 用户类型
     */
    private UserTypeEnum userType;
}
/**
 * 转换成ClientUser 的参数
 */
@Setter
@Getter
public class ClientUserParams{

    private Integer userType;

}

3. 自定义转换

/**
 * 2022/3/17
 * orika枚举转换
 *
 * @author Junisyoan
 */
public class OrikaIntegerEnumConverter extends BidirectionalConverter<Integer, IBaseEnum> {


    @Override
    public IBaseEnum convertTo(Integer value, Type<IBaseEnum> destinationType, MappingContext mappingContext) {
        for (IBaseEnum enumConstant : destinationType.getRawType().getEnumConstants()) {
            if (enumConstant.getValue() == value) {
                return enumConstant;
            }
        }
        return null;
    }

    @Override
    public Integer convertFrom(IBaseEnum source, Type<Integer> destinationType, MappingContext mappingContext) {
        return source.getValue();
    }

    @Override
    public boolean canConvert(Type<?> sourceType, Type<?> destinationType) {
        // 这里很重要
        return (sourceType.getRawType().isAssignableFrom(Integer.class) && IBaseEnum.class.isAssignableFrom(destinationType.getRawType()))
                || (destinationType.getRawType().isAssignableFrom(Integer.class) && IBaseEnum.class.isAssignableFrom(sourceType.getRawType()));
    }
}

4. 注册,我这里用静态的

/**
 * @author Junisyoan
 */
public class OrikaMap {
    private static final MapperFacade MAPPER_FACADE;

    static {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().useAutoMapping(true).mapNulls(true).build();
        // 注册自定义转换器
        mapperFactory.getConverterFactory().registerConverter(new OrikaIntegerEnumConverter());
        MAPPER_FACADE = mapperFactory.getMapperFacade();
    }


    public static <S, D> void map(S from, D to) {
        MAPPER_FACADE.map(from, to);
    }

    public static <S, D> D map(S from, Class<D> clazz) {
        return MAPPER_FACADE.map(from, clazz);
    }

    public static MapperFacade getMapperFacade() {
        return MAPPER_FACADE;
    }

    public static <S, D> List<D> mapAsList(Iterable<S> source, Class<D> destinationClass) {
        return MAPPER_FACADE.mapAsList(source, destinationClass);
    }
}

5. 运行

6. 直接抄版,可以直接运行

/**
 * @author Junisyoan
 */
public class OrikaMap {
    private static final MapperFacade MAPPER_FACADE;

    static {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().useAutoMapping(true).mapNulls(true).build();
        // 注册自定义转换器
        mapperFactory.getConverterFactory().registerConverter(new TestEnumEnumConverter());
        MAPPER_FACADE = mapperFactory.getMapperFacade();
    }

    public static <S, D> D map(S from, Class<D> clazz) {
        return MAPPER_FACADE.map(from, clazz);
    }

    // 转换器
    static class TestEnumEnumConverter extends BidirectionalConverter<Integer, BaseInterface> {

        @Override
        public BaseInterface convertTo(Integer value, Type<BaseInterface> destinationType, MappingContext mappingContext) {
            for (BaseInterface enumConstant : destinationType.getRawType().getEnumConstants()) {
                if (enumConstant.getValue() == value) {
                    return enumConstant;
                }
            }
            return null;
        }

        @Override
        public Integer convertFrom(BaseInterface source, Type<Integer> destinationType, MappingContext mappingContext) {
            return source.getValue();
        }

        @Override
        public boolean canConvert(Type<?> sourceType, Type<?> destinationType) {
            return (sourceType.getRawType().isAssignableFrom(Integer.class) && BaseInterface.class.isAssignableFrom(destinationType.getRawType()))
                    || (destinationType.getRawType().isAssignableFrom(Integer.class) && BaseInterface.class.isAssignableFrom(sourceType.getRawType()));
        }
    }

    // 接口
    interface BaseInterface{
        Integer getValue();
    }

    // 枚举
    enum TestEnum implements BaseInterface{
    
        USER(1),
        ;
        private final Integer value;

        TestEnum(Integer value) {
            this.value = value;
        }

        @Override
        public Integer getValue() {
            return value;
        }
    }

    @Data
    static class TestA{
        TestEnum userType;
    }

    @Data
    static class TestB{
        Integer userType;
    }


    public static void main(String[] args) {
        TestA a = new TestA();
        a.setUserType(TestEnum.USER);
        TestB b = OrikaMap.map(a, TestB.class);
        System.out.println(b);

        TestA c = OrikaMap.map(b, TestA.class);
        System.out.println(c);

    }
}