MapStruct属性复制框架学习笔记

        Java中DO,VO,DTO结构一样,但在意义上或者说功能上不一样,DO定义实体,VO定义视图层数据返回,DTO用于查询实体参数,通常进行转化可以自写setter/getter方法或者使用BeanUtils的属性复制方法(运行期利用反射),具体原理可以查看源码或者百度。MapStruct是同学推荐的一个开源工具,是在编译期生成对应的实体类来完成属性复制,使用方便,这里做个简单的笔记,方便以后使用。

        1、添加jar包,maven项目直接添加依赖

        
        1.1.0.Final        
        
            org.mapstruct
            mapstruct-jdk8
            ${map-struct-version}
        

        
            org.mapstruct
            mapstruct-processor
            ${map-struct-version}
        

        2、定义映射接口(也可以是抽象类)

package com.fc.mapper;

import com.fc.bean.Person;
import com.fc.bean.User;
import com.fc.bean.query.UserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

/**
 * spring模式相当于@Component注解,注册bean到spring容器
 */
@Mapper(componentModel = "spring")
public interface UserMapper {

    /**
     * 默认模式下实例获取,编译后会生成实现类
     */
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    /**
     * 实体转换,字段名相同可省略@Mappings
     *
     * @param user
     * @return
     */
    UserDTO userToUserDTO(User user);

    /**
     * 同上注释
     *
     * @param userDTO
     * @return
     */
    User userDTO2User(UserDTO userDTO);

    @Mappings({
            @Mapping(source = "id", target = "personId"),
            @Mapping(source = "sex", target = "gender")
    })
    Person userToPerson(User user);
}

        * @Mapper的componentModel有多个取值,默认是default,可以省略,这时需要定义实例的获取方式(见INSTANCE);spring取值是在spring环境中注册bean到容器,此时可以省略INSTANCE的初始化并且要注意spring容器启动时要能加载到该类,使用时可以@Autowired方式注入。

        * 实际应用default和spring方式不会同时出现,不过这里的示例这样写也是可以的并且都可以正常执行

        * 接下来是定义实体转换方法:

(1)属性名称均相同,则可以直接定义userToUserDTO方法所示,无需添加@Mappings注解来映射属性

(2)部分属性名称相同,则可以定义如userToPerson所示,使用@Mappings注解来映射属性,具体参考@Mapping注解,source是参数类的属性,target是要转换的类的属性,此外@Mapping还支持格式处理如String numberFormat() default "";以及Java表达式String expression() default "";可自行去了解更多使用情况

        3、进行转换测试(default模型需先自行编译)

public class UserMapperTest{

    private User user;

    @Before
    public void init() {
        user = new User();
        user.setId(111L);
        user.setAge(26);
        user.setCreateTime(Calendar.getInstance().getTime());
        user.setLoginName("ceChi");
        user.setLoginPassword("123456");
        user.setRealName("cece");
        user.setRole("admin");
        user.setSex('F');
        user.setUpdateTime(Calendar.getInstance().getTime());
    }

    @Test
    public void testUserToUserDTO() {
        UserDTO userDTO = UserMapper.INSTANCE.userToUserDTO(user);
        System.out.println(userDTO);
        Assert.assertEquals(userDTO.getId(), user.getId());
    }
}

(1)编译后defalut模式会在target\classes对应路径下生成接口的class文件和默认的实体类的class文件,junit测试中如上示例所示:可以直接使用INSTANCE实例来调用相应的转换方法

(2)Spring模式:需要启动Spring容器,这里可以添加启动注解,spring-tool.xml配置扫描该转换接口,如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-tool.xml"})
public class UserMapperTest{

    @Autowired
    private UserMapper userMapper;

}


    
    

     完成如上配置之后,可以直接使用注入的bean调用转换方法来完成实体类之间的转换,测试方法如下:

    @Test
    public void testUserToPerson() {
        Person person = userMapper.userToPerson(user);
        System.out.println(person);
        Assert.assertNotNull(person);
    }

       完整的简单使用到测试步骤这里基本完成,当然这只是最基础的用法,更多特例用法以及MapStruct与其它同功能的开源工具的使用对比可自行查阅相关资料。

你可能感兴趣的:(MapStruct属性复制框架学习笔记)