Orika使用

Orika用在Do和Dto之前转换,即持久化层对应的实体对象与数据传输对象之间的映射。使用Orika可以自定义CustomMapper,实现二者转换。
Orika相同功能的还有Apache的BeanUtils,Spring的BeanUtils,Dozer等。

Orika使用

接下来通过一个小demo来记录下如何使用。
新建一个springboot的web项目。

maven导入依赖包

<dependency>
    <groupId>ma.glasnost.orika</groupId>
    <artifactId>orika-core</artifactId>
    <version>1.4.6</version>
</dependency>

Do和Dto

定义两个bean,用来转换。

import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class A {
    private String nameA;
    private Integer ageA;
}

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class B {
    private String nameB;
    private Integer ageB;
}

写CustomMapper

写转换方法,extens CustomMapper。

import com.bean.A;
import com.bean.B;
import ma.glasnost.orika.CustomMapper;
import ma.glasnost.orika.MappingContext;
import org.springframework.stereotype.Component;

@Component
public class AToB extends CustomMapper<A, B> {
    @Override
    public void mapAtoB(A a, B b, MappingContext context) {
        b.setNameB(a.getNameA());
        b.setAgeB(a.getAgeA());
    }
}

controller层

import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class TestController {

    @Resource
    private MapperFacade mapper;

    @RequestMapping("/hello")
    public String getTest(@RequestBody A a){
        mapper.map(a,B.class);
        System.out.println(a);
        System.out.println(mapper.map(a,B.class));
        return "hello";
    }
}

配置文件

此时启动springboot时,controller层的mapper会为空,无法注入,应该加入自己写的Orika配置类才能让自动导入MapperFacade类。
此处也同时自定义了MapperFactoryBean 类。

package com.config;

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OrikaConfig {

    @Bean
    @ConditionalOnMissingBean(MapperFactoryBean.class)
    public MapperFactoryBean loadFactory() {
        return new MapperFactoryBean();
    }

    @Bean
    @ConditionalOnMissingBean(MapperFacade.class)
    public MapperFacade loadMapperFacade(MapperFactory factory) {
        return factory.getMapperFacade();
    }
}
import ma.glasnost.orika.CustomConverter;
import ma.glasnost.orika.Mapper;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.ClassMapBuilder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;

public class MapperFactoryBean implements FactoryBean<MapperFactory>, ApplicationContextAware {
    ApplicationContext applicationContext;

    @Nullable
    @Override
    public MapperFactory getObject() throws Exception {
        DefaultMapperFactory build = new DefaultMapperFactory.Builder().build();
        for (CustomConverter converter : applicationContext.getBeansOfType(CustomConverter.class).values()) {
            build.getConverterFactory().registerConverter(converter);
        }

        for (Mapper<?, ?> mapper : applicationContext.getBeansOfType(Mapper.class).values()) {
            build.registerMapper(mapper);
        }
        for (ClassMapBuilder<?, ?> mapper : applicationContext.getBeansOfType(ClassMapBuilder.class).values()) {
            build.registerClassMap(mapper);
        }
        return build;
    }

    @Nullable
    @Override
    public Class<?> getObjectType() {
        return MapperFactory.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

启动类加注解导入配置类


import com.config.OrikaConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import({OrikaConfig.class})
public class Demo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
}

注意:如果springboot启动后输入url报错404,很可能是目录层级不对,目录结构不符合要求。Controller包必须和AppApplication.java同级,因为@SpringBootApplication默认会去扫描同级目录或者子集目录下的所有类。
demo的目录结构如下:
在这里插入图片描述

结果

启动工程,postman发送post请求至本地,可以看到打印的结果,b已经正确赋值。

自定义的MapperFactoryBean把写的CustomMapper注册进去。
MapperFacade的map方法,其实现类MapperFacadeImpl,里面使用MappingStategy查找stategy,最后找到UserCustomMapperStategy,调用其map方法,最终调用我们自定义的CustomMapper中的mapA2B方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值