项目中的PO VO DTO是什么? 以及mapstruct的使用

命名规范

PO VO DTO是什么?

PO,持久对象,对应数据库表的对象模型。
DTO,传输对象,前端发给后端的请求对象。
VO,视图对象,后端返回给前端的对象。

mapstruct的使用

在业务逻辑开发中可能会出现3层定义的字段并不一样 我们可以使用mapstruct进行简化操作
导入依赖

        <dependency>
            <groupId>org.mapstruct</groupId>
            <!-- jdk8以下就使用mapstruct -->
            <artifactId>mapstruct-jdk8</artifactId>
            <version>1.2.0.CR1</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.2.0.CR1</version>
            <scope>provided</scope>
        </dependency>

简单测试

定义一个实体类和vo类 但是字段名不一样

@Data
@AllArgsConstructor
public class Product {
    private Integer productId;
    private String productName;
    private BigDecimal productPrice;
}
@Data
public class ProductVO {
    private Integer id;
    private String name;
    private BigDecimal price;
}

定义一个Mapper接口

@Mapper//注意该注解是mapStruct提供的不要导错
public interface ProductMapper {
    //创建mapper类
    ProductMapper mapper = Mappers.getMapper(ProductMapper.class);
    @Mappings({
            @Mapping(source = "productId",target = "id"),
            @Mapping(source = "productName",target = "name"),
            @Mapping(source = "productPrice",target = "price")
    })
    ProductVO pojo2vo(Product product);
}

测试使用

    @Test
    void contextLoads() {
        Product product = new Product(1,"hh",new BigDecimal(2.15));
        ProductVO productVO = ProductMapper.mapper.pojo2vo(product);
        System.out.println(productVO);
    }

在写好上面的映射注解后在我们使用list这些类型时也会自动转换

@Mapper//注意该注解是mapStruct提供的不要导错
public interface ProductMapper {
    //创建mapper类
    ProductMapper mapper = Mappers.getMapper(ProductMapper.class);
    @Mappings({
            @Mapping(source = "productId",target = "id"),
            @Mapping(source = "productName",target = "name"),
            @Mapping(source = "productPrice",target = "price")
    })
    ProductVO pojo2vo(Product product);
    List<ProductVO> list2vo(List<Product> list);
}

测试使用

    @Test
    void test1(){
        List<Product> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Product product = new Product(i,"电脑"+i,new BigDecimal(2));
            list.add(product);
        }
        List<ProductVO> productVOList = ProductMapper.mapper.list2vo(list);
        System.out.println(productVOList);
    }

可以正常转化过来

复杂操作

下面我们模拟一个比较复杂的情形
在上面基础上我们定义一个分类类

@Data
@AllArgsConstructor
public class Category {
    private String categoryName;
}

现在我们定义一个OrderVO类 需要上面两个类的名字

@Data
@AllArgsConstructor
public class OrderVO {
    private String product;
    private String category;
}

在映射时这样写即可

    @Mappings({
            @Mapping(source = "product.productName",target = "product"),
            @Mapping(source = "category.categoryName",target = "category")
    })
    OrderVO createOrder(Product product, Category category);

测试使用

    @Test
    void test2(){
        Product product = new Product(1,"hh",new BigDecimal(2));
        Category category = new Category("kk");
        OrderVO order = ProductMapper.mapper.createOrder(product, category);
        System.out.println(order);
    }

字段名一致情况

当然平常的情况还是字段一致的情形 此时我们只需要定义方法即可 会自动识别
定义一个dto类型和实体类名字一致

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductDto {
    private String productName;
    private BigDecimal productPrice;
}

给出转换方法
ProductDto pojo2dto(Product product);
直接使用即可

    @Test
    void test2(){
        Product product = new Product(1,"hh",new BigDecimal(2));
        ProductDto productDto = ProductMapper.mapper.pojo2dto(product);
        System.out.println(productDto);
    }
posted @ 2021-09-29 15:46  一个经常掉线的人  阅读(505)  评论(0)    收藏  举报