美文网首页
使用Orika实现DO与DTO的互转

使用Orika实现DO与DTO的互转

作者: 七岁能杀猪 | 来源:发表于2020-06-22 11:13 被阅读0次

    使用OrikaUtil实现DO与DTO的互转

    本文主要讲些什么呢

    orika是什么?orika的优缺点? orika怎么集成?

    No No No !!!
    想看这些东西的请往这边走 --> Orika Orika Orika Orika
    这些东西网上太多了,随便查一下就有了,在这里主要就是提供一个Util类的代码。
    看到这里,有同学就要开始问了,上面那些都看完之后写个Util那还不是信手捏来?
    是的,你说的都对。

    解决的主要问题

    这里主要是提供一种思路。比如你需要在DO和DTO间实现互转,但是他们之间又有些不太一样的东西。
    比如:UserDO转成UserDTO时,需要将UserDO的id赋值给UserDTO的userId,或者转回来的时候userId要赋值给id。
    在这里又有秀儿要说话了 手动set一下不就ok了吗?
    是的,你说的都对。
    先看看单元测试的效果吧。好用不好用一看就知道 (#.#)

    @Slf4j
    public class OrikaUtilTest {
    
        @Test
        public void convert() {
            UserDO userDO = new UserDO();
            userDO.setId(100L);
            userDO.setName("test");
            log.info("userDO :{}",userDO);
            //userDO :OrikaUtilTest.UserDO(id=100, name=test)
            UserDTO userDTO = OrikaUtil.convert(userDO,UserDTO.class);
            log.info("userDTO :{}",userDTO);
            //userDTO :OrikaUtilTest.UserDTO(userId=100, name=test)
            UserDO userDO1 = OrikaUtil.convert(userDTO,UserDO.class);
            log.info("userDO1 :{}",userDO1);
            //userDO1 :OrikaUtilTest.UserDO(id=100, name=test)
        }
    
        @Data
        static
        class UserDO extends BaseDO {
            private Long id;
            private String name;
        }
    
        @Data
        static
        class UserDTO{
            private Long userId;
            private String name;
        }
    }
    

    Talk is cheap, show me the code

    都看到这里来了,说明你肯定跟我一样,够懒的。 (〃''〃)

    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import lombok.experimental.UtilityClass;
    import lombok.extern.slf4j.Slf4j;
    import ma.glasnost.orika.MapperFactory;
    import ma.glasnost.orika.MappingContext;
    import ma.glasnost.orika.MappingException;
    import ma.glasnost.orika.converter.BidirectionalConverter;
    import ma.glasnost.orika.impl.DefaultMapperFactory;
    import ma.glasnost.orika.metadata.ClassMapBuilder;
    import ma.glasnost.orika.metadata.Type;
    import org.apache.commons.lang3.time.DateUtils;
    import org.apache.commons.lang3.time.FastDateFormat;
    
    import java.math.BigDecimal;
    import java.text.ParseException;
    import java.util.Date;
    
    /**
     * @author onlinever
     */
    @Slf4j
    @UtilityClass
    public class OrikaUtil {
    
        private final MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
    
        private final String entitySuffix = "DO";
    
        static {
            mapperFactory.getConverterFactory().registerConverter(new UtilDateConverter());
            mapperFactory.getConverterFactory().registerConverter(new BigDecimalConverter());
        }
    
        public <T,R> T convert(R source, Class<T> targetClass) {
            if(mapperFactory.existsRegisteredMapper(TypeFactory.<R> valueOf(source.getClass()), TypeFactory.valueOf(targetClass), false)){
                return mapperFactory.getMapperFacade().map(source, targetClass);
            }
            ClassMapBuilder<?, T> builder = mapperFactory.classMap(source.getClass(), targetClass);
            if (source instanceof BaseDO) {
                try {
                    builder = builder.field("id", StringUtils.firstCharToLower(source.getClass().getSimpleName().replaceAll(entitySuffix, "Id")));
                } catch (MappingException e) {
                    // do nothing
                }
            }
            if (BaseDO.class.equals(targetClass.getSuperclass())) {
                try {
                    builder = builder.field(StringUtils.firstCharToLower(targetClass.getSimpleName().replaceAll(entitySuffix, "Id")), "id");
                } catch (MappingException e) {
                    // do nothing
                }
            }
            builder.byDefault().register();
            return mapperFactory.getMapperFacade().map(source, targetClass);
        }
    
        private class UtilDateConverter extends BidirectionalConverter<Date, String> {
            public static final FastDateFormat DEFAULT_FAST_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
    
            @Override
            public String convertTo(Date source, Type<String> destinationType, MappingContext context) {
                return DEFAULT_FAST_DATE_FORMAT.format(source);
            }
    
            @Override
            public Date convertFrom(String source, Type<Date> destinationType, MappingContext context) {
                try {
                    return DateUtils.parseDate(source, "yyyy-MM-dd HH:mm:ss");
                } catch (final ParseException e) {
                    log.error("[OrikaUtil] Exception ", e);
                    throw new RuntimeException(e);
                }
            }
        }
    
        private class BigDecimalConverter extends BidirectionalConverter<Bigdecimal, String> {
    
            @Override
            public String convertTo(BigDecimal source, Type<String> destinationType, MappingContext context) {
                return source.toString();
            }
    
            @Override
            public BigDecimal convertFrom(String source, Type<Bigdecimal> destinationType, MappingContext context) {
                return new BigDecimal(source);
            }
        }
    }
    

    Emmm... 既然你都看到这里了,干脆点个赞再走呗 ╮(╯﹏╰)╭

    相关文章

      网友评论

          本文标题:使用Orika实现DO与DTO的互转

          本文链接:https://www.haomeiwen.com/subject/nmkxfktx.html