两个类文件,实现根据返回的id显示对应的人员信息增强返回

后台与前台交互时,由于后台存放的原始信息可能就是一些id或code,要经过相应的转换才能很好地在前台展示。

比如: select id, user_id from user

直接返回给前台时,前台可能要根据你这个user_id作为参数,再请求一次后台,获取对应的人员信息实体,以作人员信息展示。

这样多了一次IO,同时还要根据不同的场景写很多的重复代码。比如第一次IO时就连接查出对应的返回实体,或者本来不需要后续又需要这些实体就又要补上代码。

这些重复性的工作抽像出通用的代码解决,我的做法是这样:

1、首先我的人员信息是有缓存的

2、自定义一个注解@BaseId(第一个类文件)

3、写一个AOP(第二个类文件)

这个AOP在@Controller方法返回前,校验返回的实体是固定的泛型且泛型参数对应的实体类中存在被@BaseId注解的变量,就基于这个变量生成一个人员信息实体,加进这个返回实体中返回给前台。下面且看代码:

一、注解类

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BaseId {
}

二、AOP类

/*** 对GetMapping接口的返回做条件性增强,* 1、返回的类型为TableDataInfo的。里面的rows对应的实体类如果有@BaseId的,增加对应的StaffMain字段返回** @author wack* @version 1.0* @since 2023/8/3*/
@Aspect
@Slf4j
@Component
public class GetResponseAspect {private static final String STAFF_MAIN = "xxx.xxx.basis.model.staff.StaffMain";@Autowiredprivate IStaffService staffService;@AfterReturning(pointcut = "@annotation(getMapping)", returning = "jsonResult")public void beforeReturnIng(JoinPoint joinPoint, Object jsonResult, GetMapping getMapping) throws ClassNotFoundException {if (jsonResult instanceof TableDataInfo) {List rows = ((TableDataInfo) jsonResult).getRows();List newRows = new ArrayList();if (CollectionUtils.isNotEmpty(rows) && rows.get(0) != null) {Class<?> returnModel = rows.get(0).getClass();Field[] declaredFields = returnModel.getDeclaredFields();if (Arrays.stream(declaredFields).filter(obj -> obj.getAnnotation(BaseId.class) != null).findAny().isPresent()) {for (Object row : rows) {// 找到注解为baseId的字段,生成一个新的StaffMain 字段来承载对应的人员信息DynamicObject dynamicBean = new DynamicObject();Map<String, Class> allPropertyType = dynamicBean.getAllPropertyType(row);Map<String, Object> allPropertyValue = dynamicBean.getAllPropertyValue(row);for (Field declaredField : declaredFields) {if (declaredField.getAnnotation(BaseId.class) != null) {String fieldValue = ReflectUtils.getFieldValue(row, declaredField.getName());allPropertyType.put(declaredField.getName() + "Staff", Class.forName(STAFF_MAIN));allPropertyValue.put(declaredField.getName() + "Staff", staffService.getStaffCacheInfo(fieldValue));}}dynamicBean.addProperty(allPropertyType, allPropertyValue);row = dynamicBean.getObject();newRows.add(row);}if (CollectionUtils.isNotEmpty(newRows)) ((TableDataInfo) jsonResult).setRows(newRows);}}}}class DynamicObject {private Object object; //对象private BeanMap beanMap; //对象的属性private BeanGenerator beanGenerator; //对象生成器private Map<String, Class> allProperty; //对象的<属性名, 属性名对应的类型>/*** 给对象属性赋值** @param property* @param value*/public void setValue(String property, Object value) {beanMap.put(property, value);}private void setValue(Object object, Map<String, Class> property) {for (String propertyName : property.keySet()) {if (allProperty.containsKey(propertyName)) {Object propertyValue = ReflectUtils.getFieldValue(object, propertyName);this.setValue(propertyName, propertyValue);}}}private void setValue(Map<String, Object> propertyValue) {for (Map.Entry<String, Object> entry : propertyValue.entrySet()) {this.setValue(entry.getKey(), entry.getValue());}}/*** 通过属性名获取属性值** @param property* @return*/public Object getValue(String property) {return beanMap.get(property);}/*** 获取该bean的实体** @return*/public Object getObject() {return this.object;}private Object generateObject(Map propertyMap) {if (null == beanGenerator) {beanGenerator = new BeanGenerator();}Set keySet = propertyMap.keySet();for (Iterator i = keySet.iterator(); i.hasNext(); ) {String key = (String) i.next();beanGenerator.addProperty(key, (Class) propertyMap.get(key));}return beanGenerator.create();}/*** 添加属性名与属性值** @param propertyType* @param propertyValue*/public void addProperty(Map propertyType, Map propertyValue) {if (null == propertyType) {throw new RuntimeException("动态添加属性失败!");}Object oldObject = object;object = generateObject(propertyType);beanMap = BeanMap.create(object);if (null != oldObject) {setValue(oldObject, allProperty);}setValue(propertyValue);if (null == allProperty) {allProperty = propertyType;} else {allProperty.putAll(propertyType);}}/*** 获取对象中的所有属性名与属性值** @param object* @return* @throws ClassNotFoundException*/public Map<String, Class> getAllPropertyType(Object object) throws ClassNotFoundException {Map<String, Class> map = new HashMap<>();Field[] fields = object.getClass().getDeclaredFields();for (int index = 0; index < fields.length; index++) {Field field = fields[index];String propertyName = field.getName();String typeName = field.getGenericType().getTypeName();if ("long".equals(typeName)) {typeName = "java.lang.Long";}if ("int".equals(typeName)) {typeName = "java.lang.Integer";}if ("float".equals(typeName)) {typeName = "java.lang.Float";}if ("double".equals(typeName)) {typeName = "java.lang.Double";}if ("boolean".equals(typeName)) {typeName = "java.lang.Boolean";}if ("char".equals(typeName)) {typeName = "java.lang.Character";}if (typeName.indexOf("List") > -1) {typeName = "java.util.List";}Class<?> propertyType = Class.forName(typeName);map.put(propertyName, propertyType);}defaultEndType(map);return map;}private void defaultEndType(Map<String, Class> map) {map.put("createId", String.class);map.put("modifyId", String.class);map.put("createDate", Date.class);map.put("modifyDate", Date.class);}/*** 获取对象中的所有属性名与属性值** @param object* @return*/public Map<String, Object> getAllPropertyValue(Object object) {Map<String, Object> map = new HashMap<>();Field[] fields = object.getClass().getDeclaredFields();for (int index = 0; index < fields.length; index++) {Field field = fields[index];String propertyName = field.getName();Object propertyValue = ReflectUtils.getFieldValue(object, propertyName);map.put(propertyName, propertyValue);}defaultEndValue(object,map);return map;}private void defaultEndValue(Object object,Map<String, Object> map) {map.put("createId", ReflectUtils.getFieldValue(object, "createId"));map.put("modifyId", ReflectUtils.getFieldValue(object, "modifyId"));map.put("createDate", ReflectUtils.getFieldValue(object, "createDate"));map.put("modifyDate", ReflectUtils.getFieldValue(object, "modifyDate"));}}
}

在实体类中加注解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/122656.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【方法】如何取消7Z压缩文件加密的密码?

给7Z格式的压缩文件设置了密码&#xff0c;后续又不需要了&#xff0c;如何取消呢&#xff1f;如果忘记密码&#xff0c;还能取消吗&#xff1f;下面小编来分享一下方法。 首先&#xff0c;我们需要使用支持7Z格式的解压缩软件&#xff0c;如果使用的是WinRAR或者7-Zip解压缩软…

Docker从认识到实践再到底层原理(二-2)|Namespace+cgroups

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

OceanBase社区版4.x核心技术解密

数字化时代&#xff0c;各行各业的数据量呈现爆发式增长&#xff0c;对于海量数据价值的挖掘和应用&#xff0c;正成为推动创新的主要力量&#xff0c;与此同时&#xff0c;数据计算复杂度正在提升。在此背景下&#xff0c;对于数据处理的基石数据库而言&#xff0c;正面临市场…

数学建模--非多项式拟合法的Python实现

目录 1.算法异同区别 2.算法核心步骤 3.算法核心代码 4.算法效果展示 1.算法异同区别 #*************************************************************************************************************# 方法区别探究 1.对于多项式拟合你需要大致知道这些点的分布&#xf…

jsvmp逆向(补环境篇)

书接上回 上篇文章写到tx的jsxmp的算法逆向&#xff0c;文章链接在这里。初试jsvmp加密 。但是可能有伙伴觉得不够详细。 这里放一个大佬的文章链接。 https://www.52pojie.cn/thread-1521480-1-1.html 。其实就是一个变形的xtea加密。 大佬的文章已经讲了很清楚了&#…

Spring MVC入门必读:注解、参数传递、返回值和页面跳转

一、常用注解 1.1.RequestMapping 作用&#xff1a;用于映射请求路径与处理请求的方法之间的关系&#xff0c;可以用在类或方法上 。 标注在方法上 用于方法上&#xff0c;表示在类的父路径下追加方法上注解中的地址将会访问到该方法 Controller public class HelloContro…

Redis集群服务器

集群简介 试想有一家餐厅&#xff0c;如果顾客人数较少&#xff0c;那么餐厅只需要一个服务员即可&#xff0c;如图1。但是&#xff0c;当顾客人数非常多时&#xff0c;一个服务员是绝对不够的&#xff0c;如图2。此时&#xff0c;餐厅需要雇用更多的服务员来解决大量访问&…

Acwing算法心得——现代艺术(统计遍历)

大家好&#xff0c;我是晴天学长&#xff0c;先用两个一维数组维护数据&#xff0c;再统计遍历二维数组&#xff0c;需要的小伙伴请自取哦&#xff01;&#x1f4aa;&#x1f4aa;&#x1f4aa; 1 &#xff09;现代艺术 2) .算法思路 现代艺术 1.两个数组维护行和列 2.遍历数组…

git在windows上安装

介绍git工具在windows上如何安装 git官网下载地址 1.1、下载 https://github.com/git-for-windows/git/releases/download/v2.36.0.windows.1/Git-2.36.0-64-bit.exe自行选择版本&#xff0c;这里我选择的是 Git-2.36.0-64-bit这个版本 1.2、安装 安装路径选择英文且不带空格…

Vue组件之间传值

聊一聊vue里面组件之间的传值 首先总结一下vue里面传值的几种关系&#xff1a; 如上图所示, A与B、A与C、B与D、C与F组件之间是父子关系&#xff1b; B与C之间是兄弟关系&#xff1b;A与D、A与E之间是隔代关系&#xff1b; D与F是堂兄关系&#xff0c;针对以上关系 我们把组件…

Java中级面试题记录(三)

1.职业规划&#xff1f; 2.每家公司离职原因&#xff1f; 3.SpringCloud用到了哪些组件&#xff1f; GateWayNacosOpenFeignSeataHystrix 4.PG和Mysql的区别&#xff1f; 5.两种数据库的存储区别&#xff1f; 6.MySQL索引了解的内容&#xff1f; 一口气搞定索引的所有知识…

uniapp 解决跨域的问题

uniapp 解决跨域的问题 我真的是个 沙雕 找对了解决办法 写错了地方 "h5" : {"devServer" : {"disableHostCheck" : true,"https": false,"proxy" : {"/app" : {"target" : "https://192.16…

算法的时间复杂度

算法的时间复杂度 ⭐算法效率⭐时间复杂度&#x1f31f;时间复杂度&#x1f41f;时间复杂度的概念&#x1f433;例1 &#x1f41f;大O的渐进表示法&#x1f433; 例2&#x1f433;例3&#x1f433;例4&#x1f433;例5&#x1f433;例6&#x1f433;例7 ⭐算法效率 如何衡量一…

支付宝pc支付(springboot版),简单配置即可实现支付

概述 支付宝pc支付&#xff0c;只需要修改配置就可以实现支付&#xff0c;0基础小白都可以用。使用springboot编写&#xff0c;简单易用。 详细 DEMO简介 springboot整合支付宝pc支付&#xff0c;仅仅需要少量的配置&#xff0c;就可以实现pc支付。 项目截图 支付流程 用户…

sql:SQL优化知识点记录(十一)

&#xff08;1&#xff09;用Show Profile进行sql分析 新的一个优化的方式show Profile 运行一些查询sql&#xff1a; 查看一下我们执行过的sql 显示sql查询声明周期完整的过程&#xff1a; 当执行过程出现了下面这4个中的时&#xff0c;就会有问题导致效率慢 8这个sql创建…

数学建模--Topsis评价方法的Python实现

目录 1.算法流程简介 2.算法核心代码 3.算法效果展示 1.算法流程简介 """ TOPSIS(综合评价方法):主要是根据根据各测评对象与理想目标的接近程度进行排序. 然后在现有研究对象中进行相对优劣评价。 其基本原理就是求解计算各评价对象与最优解和最劣解的距离…

【力扣每日一题】2023.9.5 从两个数字数组里生成最小数字

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个数字数组&#xff0c;要我们用这两个数组里的元素组成一个数字&#xff0c;这个数字里需要同时拥有两个数组里的至少一个元…

uniapp移动端地图,点击气泡弹窗并实现精准定位

记录移动端地图map组件的使用 需求记录&#xff1a; 移动端地图部分需要展示两个定位点&#xff0c;上报点及人员定位点。通过右上角的两个按钮实现地图定位。点击对应定位气泡&#xff0c;弹出定位点的信息。 效果图如下&#xff1a; map在nvue中的使用。直接用nvue可以直接…

算法笔记:平衡二叉树

1 介绍 平衡二叉树&#xff08;AVL树&#xff09;是一种特殊的二叉搜索树&#xff08;BST&#xff09;&#xff0c;它自动确保树保持低高度&#xff0c;以便实现各种基本操作&#xff08;如添加、删除和查找&#xff09;的高效性能。 ——>时间都维持在了O(logN)它是一棵空…

科技成果鉴定之鉴定测试报告

鉴定测试 由于软件类科技成果的复杂、内部结构难以鉴别等特点&#xff0c;我们提供了软件类科技成果鉴定测试服务。软件类科技成果鉴定测试是依据其科研项目计划任务书或技术合同书&#xff0c;参照相应的国家标准对要申请鉴定的软件类科技成果进行的一种符合性测试&#xff0…