实体类的属性映射怎么可以少了它?(一)

简介: 我们都知道,随着一个工程的越来越成熟,模块划分会越来越细,其中实体类一般存于 domain 之中,但 domain 工程最好不要被其他工程依赖,所以其他工程想获取实体类数据时就需要在各自工程写 model,自定义 model 可以根据自身业务需要映射相应的实体属性。这样一来,这个映射工程貌似并不简单了。阿粉差点就犯难了……

所以阿粉今天就要给大家安利一款叫 mapstruct 的插件,它就是专门用来处理 domin 实体类与 model 类的属性映射的,我们只需定义 mapper 接口,mapstruct 在编译的时候就会自动的帮我们实现这个映射接口,避免了麻烦复杂的映射实现。

那可能有的小伙伴就要问了?为啥不用 BeanUtilscopyProperties 方法呢?不也照样可以实现属性的映射么?

这个啊,阿粉我开始也是好奇,所以就和 BeanUtils 深入交流了一番,最后才发现,BeanUtils 就是一个大老粗,只能同属性映射,或者在属性相同的情况下,允许被映射的对象属性少;但当遇到被映射的属性数据类型被修改或者被映射的字段名被修改,则会导致映射失败。而 mapstruct 就是一个巧媳妇儿了,她心思细腻,把我们可能会遇到的情况都给考虑到了(要是阿粉我也能找一个这样的媳妇儿该多好,内心笑出了猪声)

0.gif

如下是这个插件的开源项目地址和各种例子:

一、准备工作

接下来,阿粉将和大家一起去解开这个巧媳妇儿的真正面纱,所以我们还需要做一点准备工作。

1.1、了解@Mapper 注解

从 mybatis3.4.0 开始加入的 @Mapper 注解,目的就是为了不再写mapper映射文件。

我们只需要在 dao 层定义的接口上使用注解就可以实现sql语句的编写,例如:




@Select("select * from user where name = #{name}")public User find(String name);

如上就是一个简单的使用,虽然简单,但也确实体现出了这个注解的优越性,至少少写了一个xml文件。

但阿粉我今天可不是想跟你探讨 @Mapper 注解,我主要是想去看我的巧媳妇儿 mapstruct ,所以我就只是想说下 @Mapper 注解的 componentModel 属性,componentModel 属性用于指定自动生成的接口实现类的组件类型,这个属性支持四个值:

  • default: 这是默认的情况,mapstruct 不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象。
  • cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject
  • spring: 生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired方式进行注入
  • jsr330: 生成的实现类上会添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取

1.2、依赖包

首先需要把依赖包导入,主要由两个包组成:

  • org.mapstruct:mapstruct:包含了一些必要的注解,例如@Mapping。r若我们使用的JDK版本高于1.8,当我们在pom里面导入依赖时候,建议使用坐标是:org.mapstruct:mapstruct-jdk8,这可以帮助我们利用一些Java8的新特性。
  • org.mapstruct:mapstruct-processor:注解处理器,根据注解自动生成mapper的实现。
    <dependency>
        <groupId>org.mapstruct</groupId>
        <!-- jdk8以下就使用mapstruct -->
        <artifactId>mapstruct-jdk8</artifactId>
        <version>1.2.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.2.0.Final</version>
    </dependency>

好了,准备工作做完了,接下来我们就看看巧媳妇儿巧在什么地方吧。

7.jpg

二、先简单玩一把

2.1、定义实体类以及被映射类

// 实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    private Integer id;
    private String name;
    private String createTime;
    private LocalDateTime updateTime;
}
// 被映射类VO1:和实体类一模一样
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserVO1 {
    private Integer id;
    private String name;
    private String createTime;
    private LocalDateTime updateTime;
}
// 被映射类VO1:比实体类少一个字段
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserVO2 {
    private Integer id;
    private String name;
    private String createTime;
}

2.2、定义接口:

当实体类和被映射对象属性相同或者被映射对象属性值少几个时:

@Mapper(componentModel = "spring")
public interface UserCovertBasic {
    UserCovertBasic INSTANCE = Mappers.getMapper(UserCovertBasic.class);
    /**
     * 字段数量类型数量相同,利用工具BeanUtils也可以实现类似效果
     * @param source
     * @return
     */
    UserVO1 toConvertVO1(User source);
    User fromConvertEntity1(UserVO1 userVO1);
    /**
     * 字段数量类型相同,数量少:仅能让多的转换成少的,故没有fromConvertEntity2
     * @param source
     * @return
     */
    UserVO2 toConvertVO2(User source);
}

从上面的代码可以看出:接口中声明了一个成员变量INSTANCE,母的是让客户端可以访问 Mapper 接口的实现。

相关文章
|
9月前
|
SQL Java 数据库连接
2021-08-05mapper代理,几种pojo输入输出,pojo扩展通过扩展继承,映射主键普通属性映射,动态SQL,逆向工程
2021-08-05mapper代理,几种pojo输入输出,pojo扩展通过扩展继承,映射主键普通属性映射,动态SQL,逆向工程
45 0
|
5月前
|
Java 关系型数据库 MySQL
JPA中实体类属性相关注解与数据表列映射详解
JPA中实体类属性相关注解与数据表列映射详解
89 0
|
10月前
|
XML 存储 Java
Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【三】——基本映射——一对一映射
49 0
|
12月前
|
SQL Java 关系型数据库
MyBatis处理表字段和实体类属性名不一致的情况及多对一映射关系的处理
MyBatis处理表字段和实体类属性名不一致的情况及多对一映射关系的处理
155 0
实现两个不同实体类的list相同属性字段互拷
实现两个不同实体类的list相同属性字段互拷
|
Java 数据库连接 mybatis
【MyBatis】学习笔记12:通过级联属性赋值解决多对一的映射关系
【MyBatis】学习笔记12:通过级联属性赋值解决多对一的映射关系
119 0
【MyBatis】学习笔记12:通过级联属性赋值解决多对一的映射关系
直接取配置文件对应数据映射到对象中,可在代码中直接使用
直接取配置文件对应数据映射到对象中,可在代码中直接使用
|
IDE 开发工具
实体类的属性映射怎么可以少了它?(二)
我们都知道,随着一个工程的越来越成熟,模块划分会越来越细,其中实体类一般存于 domain 之中,但 domain 工程最好不要被其他工程依赖,所以其他工程想获取实体类数据时就需要在各自工程写 model,自定义 model 可以根据自身业务需要映射相应的实体属性。这样一来,这个映射工程貌似并不简单了。阿粉差点就犯难了……
实体类的属性映射怎么可以少了它?(二)
|
IDE 开发工具
实体类的属性映射怎么可以少了它?(三)
我们都知道,随着一个工程的越来越成熟,模块划分会越来越细,其中实体类一般存于 domain 之中,但 domain 工程最好不要被其他工程依赖,所以其他工程想获取实体类数据时就需要在各自工程写 model,自定义 model 可以根据自身业务需要映射相应的实体属性。这样一来,这个映射工程貌似并不简单了。阿粉差点就犯难了……
实体类的属性映射怎么可以少了它?(三)