使用Orika实现DO与DTO的互转

2020-06-22  本文已影响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... 既然你都看到这里了,干脆点个赞再走呗 ╮(╯﹏╰)╭

上一篇 下一篇

猜你喜欢

热点阅读