【Java】除了增删查改你还会什么:反射+注解

场景

最近本社会闲散人员去面试了,某公司终面的是个大佬,于是就有了下面的对话:


大佬一脸不耐烦地拿着简历:有没有做过支付啊?给我说下支付流程吧

我战战兢兢:有的有的,XX项目里接入了%*&(&*%

大佬扶了扶眼镜,皱皱眉头:你们项目任务调度用的啥?

我:xxl-job

大佬看了我一眼:说说他底层怎么实现的?

我:…

大佬:那有没有做过除了增删查改之外的东西?

我苦思冥想:(是在问我有写过框架吗…)没有的,都是在写业务,对数据处理…

大佬更加不耐烦:那你这不是码农


思考

恍恍惚惚从公司走出来后不禁陷入了思考。好像也确实是这样,工作以来基本都在写业务,已经沦为工具人一名了,但工作除了CRUD还能写啥呢?

可能是被大佬的气势压迫了,面试的时候一下想不起来还是搞了一些些除CRUD外的东西的,比如:检测U盘的插入读取文件什么的、简单封装了类似Mybatis的东东、简单的消息中间件、AOP打日志这个算吗…

反射+注解能做的

那其实现在基本框架的底层都是反射+代理模式了。这次我封装的其实是个类JDBC的玩意(泛微软件的RecordSet),在其基础上实现自动执行语句、查询后实体类赋值、根据注解查询条件、分页等等简单功能,实现就靠Java的反射和注解而已。

改造前代码:

		RecordSet rs = new RecordSet();
        String querySql = "SELECT * from formtable_main_59 where htmc = ?";
        rs.executeQuery(querySql, contractId);

        BigDecimal requestedMoney = new BigDecimal(0);

        while (rs.next()){
            String requestId = rs.getString("requestId");
            //根据流程ID进行查询
            RecordSet recordSet = new RecordSet();
            String workFlow = "SELECT * from workflow_requestbase where REQUESTID = ?";
            recordSet.executeQuery(workFlow, requestId);
            if(recordSet.next()){
                    String requestAmount = rs.getString("bcsqje");
                    requestedMoney = requestedMoney.add(new BigDecimal(StringUtils.isEmpty(requestAmount) ? "0" : requestAmount));
            }
        }

可以看到这种写法就很像原始的JDBC,SQL语句写在业务代码里,不仅臃肿且难以维护。而且代码难以复用和没有实体类,都靠复制粘贴,而且取值也很麻烦。

这个时候,就要想办法解决这些问题了,不然以后系统怎么维护?

数据处理类:
其实就是反射+注解。
在实体类上加入表名的注解,根据

public class DataSourcesHandler{

	private final RecordSet rs = new RecordSet();
	
	public <T> List<T> selectList(T condition) {
        if (null == condition) {
            return null;
        }
        List<T> result = new ArrayList<>();
        Class<?> clazz = condition.getClass();
		
		//getTableName方法为根据注解取到真正的表名
        String tableName = this.getTableName(clazz);
        StringBuilder whereKey = new StringBuilder();
        List<Object> whereValue = new ArrayList<>();
        if (ObjectUtil.isNotNull(condition)) {
            Field[] fields = this.getAllFields(clazz);
            for (Field field : fields) {
                String fieldName = this.getFieldName(field);
                Object fieldValue = this.getFieldValue(condition, field.getName());
                if (null != fieldValue) {
                    whereKey.append(" and ").append(fieldName).append(" = ?");
                    whereValue.add(fieldValue);
                }
            }
        }

		//开始拼接SQLyuju
        String executeSql = "select * from " + tableName + " where 1 = 1 " + whereKey.toString();
        rs.executeQuery(executeSql, whereValue);

		//根据实体类进行赋值
        Field[] fields = getAllFields(clazz);
        Map<String, Object> map;
        while (rs.next()) {
            map = new LinkedHashMap<>();
            String[] columnNames = rs.getColumnName();
            for (Field field : fields) {
                String fieldName = this.getFieldName(field);
                for (String columnName : columnNames) {
                    if (columnName.toLowerCase().equals(fieldName.toLowerCase())) {
                        map.put(field.getName(), rs.getString(fieldName));
                    }
                }
            }
            result.add((T) JSON.parseObject(JSON.toJSONString(map), condition.getClass()));
        }
        return result;
    }
}


    private String getTableName(Class<?> clazz) {
        TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
        if (null != tableNameAnnotation) {
            return tableNameAnnotation.value();
        } else {
            TableMapping workflowMapping = clazz.getAnnotation(TableMapping.class);
            if (null != workflowMapping) {
                String mappingName = workflowMapping.value();
                String tableName = getMappingTableName(mappingName);
                if (null != tableName) {
                    return tableName;
                } else {
                    log.info("注解[WorkflowMapping]的值[" + mappingName + "]没有查询到数据");
                    throw new ECException("注解[WorkflowMapping]的值[" + mappingName + "]没有查询到数据");
                }
            } else {
                log.info("CLASS【" + clazz.getTypeName() + "】中未没有包含注解[TableName]或[WorkflowMapping]");
                throw new ECException("CLASS【" + clazz.getTypeName() + "】中未没有包含注解[TableName]或[WorkflowMapping]");
            }

        }
    }

改造后的业务代码:
只需要实例化数据处理类,调用里面的selectList方法,就可以实现根据实体类里的值查询并且赋值。
这样的代码就简洁多了,并且后续维护成本也低很多。

private final DataSourcesHandler dataSources = new DataSourcesHandler();

List<QualificationsOrderByDeal> buyList = dataSources.selectList(
	new QualificationsOrderByDeal().setHtmc(String.valueOf(contractId)));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值