Java 注解、反射、泛型使用实践 | 实现一个通用的实体类字段计算工具

Java 注解、反射、泛型使用实践

通过 注解、反射、泛型 实现一个通用的实体类字段计算工具

近期工作中,在做的项目,需要进行各种报表的计算。
对象字段间进行加减乘除等计算,以及汇总计算

场景:
假设有这样一个实体类:

@Data
public class ClockingInEntity {
	/**
	 * 迟到次数
	 */
	private Integer lateCount;

	/**
	 * 缺卡次数
	 */
	private Integer notClockInCount;

	/**
	 * 缺卡扣款
	 */
	private BigDecimal notClockInWithhold;

	/**
	 * 迟到扣款
	 */
	private BigDecimal lateWithhold;
}

用户填写 迟到次数和缺卡次数,需要自动计算缺卡扣款和迟到扣款:


缺卡扣款 = 缺卡次数 * 100
迟到扣款 = 迟到次数 * 200


如果字段很少的话,使用代码的方式来计算没啥问题,但是这个系统有很多地方都要进行各字段之间的计算,如果使用硬编码进行计算,那么公式改变了,就得改代码逻辑。

我想能否将公式配置到某个地方,再写一个触发计算的方法,来计算呢?如果计算公式改变,那么改变配置的公式即可。


于是,我想到了使用注解来配置公式。
接着,开始了 Java 注解和反射 的详细学习,之前只是随便看了下,没用过。

通过注解将公式配置到注解参数上,于是实体类变成了:
ClockingInEntity.Java

@Data
public class ClockingInEntity {
    /**
     * 迟到次数
     */
    @USummaryAnnotation(needSum = true)
    private Integer lateCount;

    /**
     * 缺卡次数
     */
    @USummaryAnnotation(needSum = true)
    private Integer notClockInCount;

    /**
     * 缺卡扣款
     */
    @USummaryAnnotation(needSum = true)
    @UFormulaAnnotation(formula = "[notClockInCount]*100",accuracy = 2,sort = 1)
    private BigDecimal notClockInWithhold;

    /**
     * 迟到扣款
     */
    @USummaryAnnotation(needSum = true)
    @UFormulaAnnotation(formula = "[lateCount]*200",accuracy = 2,sort = 2)
    private BigDecimal lateWithhold;


    public ClockingInEntity(Integer lateCount, Integer notClockInCount) {
        this.lateCount = lateCount;
        this.notClockInCount = notClockInCount;
    }

    public ClockingInEntity() {
    }
}

然后通过反射获取注解上的公式等配置信息进行计算,并将结果赋值到对应字段即可

为了让计算工具具有通用行,使用了泛型


public interface CalcService {
	/**
	 * 对一个实体类进行计算 配合 UFormulaAnnotation 注解使用
	 * @param entityClass 目标实体 clazz
	 * @param <T>
	 * @return
	 */
	<T> T doOneEntityCalc(Class<T> entityClass, T entity);

	/**
	 * 对实体列表进行计算 UFormulaAnnotation 注解使用
	 * @param entityClass 目标实体 clazz
	 * @param entities 实体列表
	 * @param <T>
	 * @return
	 */
	<T> List<T> doEntitiesCalc(Class<T> entityClass, List<T> entities);


	/**
	 * 汇总计算 USummaryAnnotation 注解使用
	 * @param entityClass 目标实体 clazz
	 * @param entities 实体列表
	 * @param <T>
	 * @return
	 */
	<T> T doSummaryCalc(Class<T> entityClass, List<T> entities,T summaryEntity);

	/**
	 *两个实体相除 UDivisionAnnotation 注解使用
	 * @param entityClass 目标实体 clazz
	 * @param divisorEntity 除数
	 * @param dividendEntity 被除数
	 * @param resultEntity 结果实体
	 * @param <T>
	 * @return
	 */
	<T> T doEntityDivisionCalc(Class<T> entityClass, T divisorEntity, T dividendEntity, T resultEntity);

CalcServiceImpl.java 代码太长这里就不贴了,可到 https://gitee.com/zranfly/easy-calc.git 获取

最终通过简单的调用即可进行实体间字段计算,效果如下:

public class MainTest {
    public static void main(String[] args) {
        CalcService calcService = new CalcServiceImpl();

        ClockingInEntity entity1 = new ClockingInEntity(2,10);
        ClockingInEntity entity2 = new ClockingInEntity(3,11);
        ClockingInEntity entity3 = new ClockingInEntity(4,23);

        List<ClockingInEntity> entities = Lists.newArrayList(entity1,entity2,entity3);

        // 单个实体计算
        System.out.println("===========计算前================");
        System.out.println(JSON.toJSONString(entity1));
        System.out.println("===========计算后================");
        calcService.doOneEntityCalc(ClockingInEntity.class,entity1);
        System.out.println(JSON.toJSONString(entity1));

        // 多个实体计算
        System.out.println("===========批量计算================");
        calcService.doEntitiesCalc(ClockingInEntity.class,entities);
        System.out.println(JSON.toJSONString(entities));

        // 汇总计算
        System.out.println("===========汇总计算================");
        ClockingInEntity totalEntity = calcService.doSummaryCalc(ClockingInEntity.class, entities, new ClockingInEntity());
        System.out.println(JSON.toJSONString(totalEntity));

    }

输出结果

===========计算前================
{"lateCount":2,"notClockInCount":10}
===========计算后================
{"lateCount":2,"lateWithhold":400.00,"notClockInCount":10,"notClockInWithhold":1000.00}
===========批量计算================
[{"lateCount":2,"lateWithhold":400.00,"notClockInCount":10,"notClockInWithhold":1000.00},{"lateCount":3,"lateWithhold":600.00,"notClockInCount":11,"notClockInWithhold":1100.00},{"lateCount":4,"lateWithhold":800.00,"notClockInCount":23,"notClockInWithhold":2300.00}]
===========汇总计算================
{"lateCount":9,"lateWithhold":1800.00,"notClockInCount":44,"notClockInWithhold":4400.00}

代码获取:https://gitee.com/zranfly/easy-calc.git

代码还有优化空间,后续有时间再做优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值