orika 工具下划线转驼峰不同字段名映射

1.问题:

业务需要把第三方接口的带下划线的字段规范为驼峰的字段
第三方接口的bean对象:

public class ObjectsDetail extends XMLElementData implements Serializable {
    private static final long serialVersionUID = 5080447582610246168L;
    private String objectclass;
    private String view_guid;
    private String group_guid;
    private String user_guid;
    private String all_path_name;
    private String original_sort;
 }

要转换为驼峰的本地对象

@Data
@NoArgsConstructor
@AllArgsConstructor
public class H4aUsers {
   
    private String objectclass;
  
    private String viewGuid;
 
    private String groupGuid;
  
    private String userGuid;
    
    private String allPathName;
  
    private String originalSort;
 }

2.解决思路

2.1 使用自带的BidirectionalConverter接口

发现只能同字段名称不同字段类型转换,像String转Date,list转String
参考博客http://www.lxiaoyu.com/p/283285

2.2 使用orika自带的field方法实现

传入一个map对象即可

    /**
     * Map a field in both directions
     * 
     * @param fieldNameA
     *            property name in type A
     * @param fieldNameB
     *            property name in type B
     * @return
     */
    public ClassMapBuilder<A, B> field(String fieldNameA, String fieldNameB) {
        return fieldMap(fieldNameA, fieldNameB).add();
    }
2.2.1 使用hutool的反射工具获取两个对象的所有字段

使用CharSequenceUtil.toCamelCase()方法把下划线转驼峰字段判断,然后映射到map集合返回

  public Map<String, String> getCamelCaseMap(Class<?> source, Class<?> des) {
        //带下划线的实体类字段集合
        Field[] sourceFields = ReflectUtil.getFields(source);
        log.info("getCamelCaseMap sourceFields = " + sourceFields.length);
        //带驼峰的实体类字段集合
        Field[] desFields = ReflectUtil.getFields(des);
        log.info("getCamelCaseMap desFields = " + desFields.length);
        //只获取字段名集合
        List<String> sources = Arrays.stream(sourceFields).map(Field::getName).collect(Collectors.toList());
        Map<String, String> fieldsMap = Maps.newHashMap();
        //遍历驼峰字段集合
        for (Field desField : desFields) {
            String name = desField.getName();
            //判断是否和转换后的字段相同
            Optional<String> first = sources.stream().filter(s -> Objects.equals(CharSequenceUtil.toCamelCase(s), name)).findFirst();
            //相同则放入map映射
            if (first.isPresent()) {
                fieldsMap.put(first.get(), name);
            }else {
                log.info("getCamelCaseMap name = " + name);
            }
        }
        log.info("getCamelCaseMap fieldsMap = " + fieldsMap.size());
        return fieldsMap;
    }

2.2.2 把获取的map传给orika

     /**
     * 获取自定义映射
     *
     * @param toClass       映射类
     * @param dataClass     数据映射类
     * @param configMap     自定义配置
     * @param useDefaultMap 是否使用默认映射
     * @return 映射类对象
     */
    private <E, T> MapperFacade getMapperFacade(Class<E> toClass, Class<T> dataClass, Map<String, String> configMap, List<CustomConverter<?, ?>> converter, boolean useDefaultMap) {
        String mapKey = dataClass.getCanonicalName() + "_" + toClass.getCanonicalName();
        MapperFacade mapperFacade = CACHE_MAPPER_FACADE_MAP.get(mapKey);
        if (Objects.isNull(mapperFacade)) {
            MapperFactory factory = new DefaultMapperFactory.Builder().build();
            if (!converter.isEmpty()) {
                converter.forEach(con -> factory.getConverterFactory().registerConverter(con));
            }
            ClassMapBuilder classMapBuilder = factory.classMap(dataClass, toClass);
            //映射不同字段名的实体
            if (CollUtil.isNotEmpty(configMap)) {
                configMap.forEach(classMapBuilder::field);
            }
            if (useDefaultMap) {
                classMapBuilder.byDefault();
            }
            classMapBuilder.register();
            mapperFacade = factory.getMapperFacade();
            CACHE_MAPPER_FACADE_MAP.put(mapKey, mapperFacade);
        }
        return mapperFacade;
    }
 /**
     * 映射实体(自定义配置)
     *
     * @param toClass   映射类对象
     * @param data      数据(对象)
     * @param configMap 自定义配置
     * @return 映射类对象
     */
    public <E, T> E map(Class<E> toClass, T data, Map<String, String> configMap) {
        MapperFacade mapperFacade = this.getMapperFacade(toClass, data.getClass(), configMap, new ArrayList<>(), true);
        return mapperFacade.map(data, toClass);
    }

2.2.3 测试

   @Test
    public void testCamlCase() {
        ObjectsDetail objectsDetail = new ObjectsDetail();
        objectsDetail.setOrg_class("1111");
        objectsDetail.setOrg_guid("2222");
        objectsDetail.setObjectclass("33333");
        objectsDetail.setView_guid("4444");
        objectsDetail.setUser_guid("5555");
        objectsDetail.setAll_path_name("666666");
        objectsDetail.setOriginal_sort("7777");


        Map<String, String> camelCaseMap = OrikaTool.getInstance().getCamelCaseMap(ObjectsDetail.class, H4aUsers.class);
        H4aUsers map = OrikaTool.getInstance().map(H4aUsers.class, objectsDetail, camelCaseMap);
        System.out.println("map = " + map);

    }

测试结果:

3.注意

转驼峰的实体一定要实现无参构造和有参构造,orika是根据构造方法获取参数去映射的

@Data
@NoArgsConstructor
@AllArgsConstructor
public class H4aUsers {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值