推荐GET/SET 提效工具

简介: 推荐GET/SET 提效工具

作者|饭哥

111.gif

本文简要介绍了 GenerateAllSetter / Lombok / Mapstruct 三种法器,各自应用场景稍有不同,供大家参考选择。



背景


日常开发过程中,往往绕不开 DTO / DO / VO 等基础对象定义,或对象属性转换等相关编码。针对对象属性 Getter / Setter 场景,本文简要介绍了 GenerateAllSetter / Lombok / Mapstruct 三种法器,各自应用场景稍有不同,供大家参考选择。


GenerateAllSetter


 简介


GenerateAllSetter 是什么?

GenerateAllSetter 是一款 IDEA 插件,可为对象属性批量生成 Setter 代码。


  应用场景


什么时候用?

对象属性赋值,希望自动生成对象所有属性的 Setter 方法。


  基本用法


怎么用?


  • IDEA 安装插件 GenerateAllSetter


IDEA-Preferences-Plugins,搜索 GenerateAllSetter ,一键安装插件。插件安装后,若未生效请重启 IDEA 。

1.jpg

  • 一键生成对象 Setter 方法


GenerateAllSetter 安装完成后,选中目标对象,单击左边灯泡或使用快捷键 MacOS( Option + 回车)/ Windows( Alt + 回车),即可一键生成对象的 setXxx 方法。2.jpg

例如,点击 “Generate all setter with default value”,一键生成对象所有 Setter 方法(预设默认值)。

3.jpg

Lombok


 简介


Lombok 是什么?

Lombok 是一款 Java 开发插件,可在编译期自动生成对象的基础方法。例如, POJO 类的构造器、 Getter/Setter 、equals 和 toString 等方法,借助 Lombok 只需添加相应注解即可自动生成,无需手动定义。

 应用场景


什么时候用?

对象基础方法定义,希望自动生成 Getter / Setter / toString 等基础方法,让类定义更简洁。


 使用方法


怎么用?


  • 引入 Lombok 依赖







<dependency>  <groupId>org.projectlombok</groupId>  <artifactId>lombok</artifactId>  <version>1.16.18</version></dependency>


  • 核心注解@Data


作用于类时,为类的所有属性生成 Getter/Setter 方法,并生成类的 toString / equals / canEquals / hashCode 方法。Lombok 自动生成 Getter / Setter 方法时,不会覆盖显式定义的 Getter / Setter 方法。


@Setter:作用于类时,为类的所有属性生成 Setter 方法;作用于类的某个属性时,为该属性生成 Setter 方法。

@Getter:作用于类时,为类的所有属性生成 Getter 方法;作用于类的某个属性时,为该属性生成 Getter 方法。

@AllArgsConstructor:作用于类时,生成该类的全参构造函数。

@NoArgsConstructor:作用于类时,生成该类的无参构造函数。

@ToString:作用于类时,生成对应的 toString 方法。

@EqualsAndHashCode:作用于类时,重写 equals 和 hashcode 方法。

@Builder:通过 Builder 链式创建新对象,不需要逐行添加 Setter 方法,可简化代码行数,提升编码体验。

@NotNull:作用于方法入参,如果对应入参传了 null 值,将抛出空指针异常。

@Synchronized:作用于方法,可锁定指定对象;如果不指定,则默认创建一个对象锁定。

@Accessors(chain = true):使用链式设置属性,Setter 方法返回 this 对象。

@RequiredArgsConstructor:在类上添加 @RequiredArgsConstructor(staticName = "of") 时,生成一个静态方法。

@FieldDefaults:设置属性使用范围,如 private / public 等,也可以设置属性是否被 final 修饰。

@Cleanup: 关闭流对象、连接点等。


示例 1 :


@Data 注解,自动生成对象的 Getter、Setter、equals、hashcode 和 toString 方法。

4.jpg

编译后生成代码如下:

5.jpg

示例 2 :


@Getter / @Setter / @AllArgsConstructor / @NoArgsConstructor / @Builder 注解,分别生成对象的 Getter、Setter、全参构造器、无参构造器和 Builder 方法。

5.jpg

编译后生成代码如下:

6.jpg

更多功能,可参考官网:https://projectlombok.org


Mapstruct


 简介


Mapstruct 是什么?

Mapstruct 是一款 Java 属性映射工具,可实现源对象和目标对象之间的属性映射。通过 Mapstruct 定义 Mapper 接口,Mapstruct 将在编译期生成该 Mapper 接口的实现类,该实现类内部封装了对象属性转换逻辑。值得注意的是,Spring 和 Apache 提供了 BeanUtils 工具,同样可实现对象属性转换,但由于底层基于反射实现,需在运行期进行属性转换,效率相对较低,因此应尽量避免使用 BeanUtils 工具。


  应用场景


什么时候用?

对象间属性映射,希望自动映射关联属性,或自定义不同属性的映射关系。


  使用方法


怎么用?


  • 引入 Mapstruct 依赖







<dependency>  <groupId>org.mapstruct</groupId>  <artifactId>mapstruct</artifactId>  <version>${org.mapstruct.version}</version></dependency>


  • 对象定义


举例,PosOrder 对象转换为 WorkOrder 对象,两个对象属性不完全对等。

PosOrder(订单):

@Data
public class PosOrder implements Serializable {
    private static final long serialVersionUID = 690962385718485646L;
    /**
     * 记录生成时间
     */
    private Date gmtCreate;
    /**
     * 订单ID
     */
    private Long id;
    /**
     * 买家信息
     */
    private User user;
    // ...
}

WorkOrder(工单):

@Data
public class WorkOrder implements Serializable {
    private static final long serialVersionUID = 890962385718485649L;
    /**
     * 记录生成时间
     */
    private Date gmtCreate;
    /**
     * 工单ID
     */
    private String workNo; 
    /**
     * 买家信息
     */
    private Customer customer;
    /**
     * 删除标记
     */
    private String isDeleted;
    /**
     * 记录序列ID
     */
    private String sequenceId;
}
  • WorkOrderMapper 转换器定义


定义接口 WorkOrderMapper,并添加类注解 @Mapper ,MapStruct 会自动生成对应实现类。

@Mapper 的 componentModel 属性,用于指定实现类的类型。

  1. default:通过 Mappers.getMapper(Class) 方式获取实例对象;
  2. spring:接口实现类自动添加注解 @Component,可通过 @Autowired 方式注入。

@Mapping:属性映射,若源对象属性与目标对象属性名字一致,将自动映射同名属性;此外,支持自定义属性映射关系。

  1. source:源属性
  2. target:目标属性
  3. dateFormat:String 和 Date 日期相互转换
  4. ignore: 忽略这个字段

WorkOrderMapper 代码如下:

@Mapper
public interface WorkOrderMapper {
    /**
     * Mapper实例
     */
    WorkOrderMapper INSTANCE = Mappers.getMapper(WorkOrderMapper.class);
    /**
     * PosOrder 转换为 WorkOrder
     * 说明:
     * - PosOrder.id 映射为 WorkOrder.workNo
     * - PosOrder.user.userName 映射为 WorkOrder.customer.name
     * - WorkOrder.isDeleted 默认为常量"n"
     * - WorkOrder.sequenceId 通过 getSequenceId() 方法动态生成
     */
    @Mapping(target = "workNo", source = "id" )
    @Mapping(target = "customer.name", source = "user.userName")
    @Mapping(target = "isDeleted", constant = "n")
    @Mapping(target = "sequenceId",  expression="java(getSequenceId())")
    WorkOrder transFrom(PosOrder posOrder);
    /**
     * WorkOrder 转换为 PosOrder
     */
    @InheritInverseConfiguration(name="transTo")
    PosOrder transTo(WorkOrder workOrder);
    /**
     * 映射器可添加自定义方法,如获取序列ID
     */
    default String getSequenceId(){
        String uuid = UUID.randomUUID().toString();
        return uuid;
    }
}


编译后生成的 Mapper 实现类如下:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2021-09-27T21:55:09+0800",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_151 (Oracle Corporation)"
)
public class WorkOrderMapperImpl implements WorkOrderMapper {
    @Override
    public WorkOrder transFrom(PosOrder posOrder) {
        if (posOrder == null) {
            return null;
        }
        WorkOrder workOrder = new WorkOrder();
        workOrder.setCustomer(userToCustomer(posOrder.getUser()));
        if (posOrder.getId() != null) {
            // Mapping 映射属性生成
            workOrder.setWorkNo(String.valueOf(posOrder.getId()));
        }
        // 同名属性自动映射
        workOrder.setGmtCreate(posOrder.getGmtCreate());
        // 设置默认值
        workOrder.setIsDeleted("n");
        // 自定义方法
        workOrder.setSequenceId(getSequenceId());
        return workOrder;
    }
    @Override
    public PosOrder transTo(WorkOrder workOrder) {
        if (workOrder == null) {
            return null;
        }
        PosOrder posOrder = new PosOrder();
        posOrder.setUser(customerToUser(workOrder.getCustomer()));
        if (workOrder.getWorkNo() != null) {
            posOrder.setId(Long.parseLong(workOrder.getWorkNo()));
        }
        posOrder.setGmtCreate(workOrder.getGmtCreate());
        return posOrder;
    }
    /**
     * 内部对象映射
     */
    protected Customer userToCustomer(User user) {
        if ( user == null ) {
            return null;
        }
        Customer customer = new Customer();
        customer.setName(user.getUserName());
        // 同名属性自动映射
        customer.setId(user.getId()); 
        return customer;
    }
  /**
     * 内部对象映射
     */
    protected User customerToUser(Customer customer) {
        if ( customer == null ) {
            return null;
        }
        User user = new User();
        user.setUserName( customer.getName() );
        user.setId( customer.getId() );
        return user;
    }

对于更复杂的属性转换,Mapstruct 还支持 List / Map / 枚举映射 / 时间 等类型转换。需要提醒的是,编译后最好检查 Mapstruct 自动生成的代码,以避免可能的异常情况,如类型自动转换可能丢失精度等。


  • 借助 WorkOrderMapper 转换器实现对象转换


定义 WorkOrderMapper 后,即可直接使用 Mapper 实例将 PosOrder 转换为 WorkOrder 对象。



WorkOrder workOrder =  WorkOrderMapper.INSTANCE.transfer(posOrder);


在上面例子中, 我们通过 Mappers.getMapper(xxx.class) 方式获取对应 Mapper 。接口本身定义了 INSTANCE 字段,用于获取 Mapper 实例。此外,Mapstruct 支持 Spring 依赖注入方式,通过 @Mapper(componentModel = “spring”) 即可将当前 Mapper 注册进 Spring 容器,后续在其它类直接注入即可。


总结


本文简要介绍了三种对象属性编码提效工具。


  1. GenerateAllSetter 用于自动生成对象属性的 Setter 方法;
  2. Lombok 用于自动生成类的 Getter / Setter / toString 等基础方法;
  3. Mapstruct 用于实现两个对象之间的属性转换。


三种工具都为开发者提供了较好的便捷性,并一定程度上提升了代码可读性。值得注意的是,很多工具可在编译期自动生成代码,但使用者应该熟悉其基本原理,以避免可能的异常情况,出现问题能及时感知与排查。


相关文章
|
7月前
|
缓存 监控 Java
ThreadLocal 源码解析get(),set(), remove()用不好容易内存泄漏
ThreadLocal 源码解析get(),set(), remove()用不好容易内存泄漏
90 1
|
7月前
idea快速生成get set 构造方法的快捷键
idea快速生成get set 构造方法的快捷键
235 0
|
7月前
|
存储 NoSQL Ubuntu
在Ubuntu上安装Redis并学习使用get、set和keys命令
在Ubuntu上安装Redis并学习使用get、set和keys命令
|
JavaScript
TypeScript get 与 set 的使用
TypeScript get 与 set 的使用
185 0
|
1月前
|
Java Windows
IDEA不使用lombok,如何快速生成get和set方法
【11月更文挑战第10天】在 IntelliJ IDEA 中生成 `get` 和 `set` 方法有多种方式:通过菜单操作、使用快捷键或自定义模板。菜单操作包括选择“Code”菜单中的“Generate...”,快捷键为“Alt + Insert”。自定义模板可在“File”-&gt;“Settings”-&gt;“Editor”-&gt;“Code Style”-&gt;“Java”中设置。批量生成时,可多选变量一次性生成。
idea按住alt + insert 没有出现get和set方法怎样解决
idea按住alt + insert 没有出现get和set方法怎样解决
|
2月前
|
C#
SET访问器和GET访问器
SET访问器和GET访问器
34 2
|
4月前
|
API
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
|
4月前
|
Java Linux 开发者
|
4月前
|
缓存 NoSQL Redis
【Azure Redis 缓存】Azure Cache for Redis 是否记录具体读/写(Get/Set)或删除(Del)了哪些key呢?
【Azure Redis 缓存】Azure Cache for Redis 是否记录具体读/写(Get/Set)或删除(Del)了哪些key呢?