不要轻易删除没有用到的代码

说明:在周志明著作《凤凰框架》的最后一章,提到软件研发的一个概念——“架构腐化”,大意是代码越来越多,脏代码无法避免。延缓架构腐化需要研发团队都有较高的水平,对项目架构有整体的把握,并且富有责任心,及时清理不必要的代码。

本文介绍一种项目中方法无显性调用,但不可删除的代码场景,作为以后清理代码的预防针——不是所有没调用的代码都能删除。

场景

一个分页查询接口,传入一个DTO对象,DTO中包含前端传递的条件参数,查询返回符合条件的记录。

基础操作

分页查询接口

    @PostMapping("/page")
    public List<User> list(@RequestBody UserDTO userDTO) {
        return userService.list(userDTO);
    }

DTO 对象

import lombok.Data;

import java.io.Serializable;

@Data
public class UserDTO implements Serializable {

    private Integer age;

    private Integer pageNo;

    private Integer pageSize;
}

Service 实现类,计算偏移量,传给 Mapper

    @Override
    public List<User> list(UserDTO userDTO) {
        Integer offset = (userDTO.getPageNo() - 1) * userDTO.getPageSize();
        return userMapper.list(userDTO, offset);
    }

查询 SQL,查询大于某年龄的记录

    <select id="list" resultType="com.hezy.pojo.User">
        select * from tb_user
        <where>
            <if test="userDTO.age != null ">
                and age > #{userDTO.age}
            </if>
        </where>
        limit #{offset}, #{userDTO.pageSize}
    </select>

查询结果

在这里插入图片描述

骚操作

上面代码,偏移量 offset 是在 Service 实现类里计算的,其实可以放到 DTO 对象里,如下:

import lombok.Data;

import java.io.Serializable;

@Data
public class UserDTO implements Serializable {

    private Integer age;

    private Integer pageNo;

    private Integer pageSize;

    /**
     * 计算偏移量
     */
    public Integer getOffset() {
        return (pageNo - 1) * pageSize;
    }
}

然后你以为是在 Service 实现类里调用方法吗?其实根本不用,直接在 Mapper.xml 中使用

(Service 实现类,去掉计算 offset)

    @Override
    public List<User> list(UserDTO userDTO) {
        return userMapper.list(userDTO);
    }

(Mapper 不需要传 offset)

    List<User> list(@Param("userDTO") UserDTO userDTO);

(Mapper.xml 直接用 对象.offset 获取)

    <select id="list" resultType="com.hezy.pojo.User">
        select * from tb_user
        <where>
            <if test="userDTO.age != null ">
                and age > #{userDTO.age}
            </if>
        </where>
        limit #{userDTO.offset}, #{userDTO.pageSize}
    </select>

敲的时候,编辑器都没有提示对象中有这个字段

在这里插入图片描述

看,还是能查出来

在这里插入图片描述

分析

回过头来看这个 DTO ,getOffset() 方法没有显性调用,但却能在 Mapper.xml 中产生 offset 变量。

两种解释:

(1)Mybatis 框架在实例化 DTO 时,调用了对象里的 getter() 方法,产生了未被定义的属性;

(2)Mapper.xml 中 #{DTO.xx} 时,实际上就是 DTO.getXx(),因为 DTO 有定义方法,所以能获取到值;

在这里插入图片描述

不管是哪种,这种写法都是行得通的。并且这种写法十分高效,可以将不属于 Service 层的一些计算赋值逻辑放入到 DTO 中,直接绑定到 Mapper.xml 中。

如查询距离当前时间 30 天以内的记录,就可以在 DTO 中定义一个方法,如下:

    /**
     * 30 天之前的日期
     */
    public Date getBeginDate() {
        return Date.from(LocalDate.now().minusDays(30).atStartOfDay().toInstant(ZoneOffset.UTC));
    }

Mapper.xml 直接用

    <select id="list" resultType="com.hezy.pojo.User">
        select * from tb_user
        <where>
            <if test="userDTO.age != null ">
                and age > #{userDTO.age}
            </if>
            and create_time > #{userDTO.beginDate}
        </where>
        limit #{userDTO.offset}, #{userDTO.pageSize}
    </select>

看控制台打印的 SQL,获取到了 DTO 中的方法返回值

在这里插入图片描述

对于不懂这套写法的程序员,可能看到 DTO 中一堆没有调用的方法,且没有明确注释说明,就很有可能把这些方法作为不必要的代码清除掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何中应

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值