业务场景:

在很多的业务系统中,erp,crm系统中,有许多的对象信息都是拆开来的,例如一个商品,那可能他的商品名称,商品等主要信息放在一个表(衍生出来一个对象),他的附属信息(商品图片,规格,价格等)可能会在其他的多个表(对象)中,这个时候一般我们想到的操作是:

1.将主要的对象查询出来

2.利用主要对象和其他附属信息的关联字段来查询主对象关联的附属信息对象列表

3.将查询到的附属信息和主对象关联的字段作为key,附属信息作为value组装map

4.组装一个VO包装所有信息,操作:

  for( 主对象 : 主对象列表){

    新建VO,将主对像信息填充进去;

    根据主对像关联附属信息的字段在map中获取附属信息拿到附属信息对象

    将附属信息填充到VO 

  }

5.得到想要的组装对象

这里看起来业务场景还是比较简单,但是有两个问题:

1.这里用户的操作是查询list,组装map,根据key获取map,将对象放到VO,如果对象有多个,那么用户的代码里面会有很多重复的,占据大篇幅代码量的该操作序列代码;

2.如果附属对象有多个对象,那就会有多个map对象,这些对象内容很大,在全部循环结束前,所有的对象都不会被释放,占用着内存;

这个工具类的核心思想是采用反射,为了增加反射速度,引用reflectasm的类库,并且将MethodAccess对象通过classType缓存起来,加快反射执行速度:

类的字段:

private static final int MAX_CACHE_FOR_METHOD_ACCESS = 256;    // 规定最大的缓存数量
private static Map<Class, MethodAccess> methodAccessMap;    // 缓存存放的map,在第一次使用时候才初始化

类的签名:

public void setField(Object obj1, String str1, Object obj2);//将obj1的名为str1的字段值设置为obj2

在list中拿一个对象,取出字段名为<keyName>的字段值,在messMap中查找value,将value设置到<valueName>的字段中去

isStr判断valueName的字段是否是字符串类型,如果是,对于null的处理会显示未"", 如果不是则不做处理
/**
* 批量设置内容到list中
* @param list 需要附加内容的list
* @param messMap 提供信息的map,key=keyName
* @param keyName key(1.list中有)
* @param valueName valueName(2.list中有)

* @param isStr 设置的值是否是字符串
*/
public static void setField(List list, Map messMap, String keyName, String valueName, boolean isStr);
public void setFieldStr(List, Map, String, String); // 调用setField(list, map, String, String, true)
public void setField(List, Map, String, String);// 调用setField(list, map, String, String, false)

private void initmethodAccessMap();  //初始化缓存map
private void delOneFromMap;    // 从map中随机清理一个
private void addMethodAccessCache(Class, MethodAccess);  // 添加缓存到map
private MethodAccess getMethodAccess(Class);  // 通过class获取缓存的methodAccess

主要代码实现:

  /**
* 批量设置内容到list中
* @param list 需要附加内容的list
* @param messMap 提供信息的map,key=keyName
* @param keyName key(1.list中有)
* @param valueName valueName(2.list中有)
* @param isStr 设置的值是否是字符串
*/
public static void setField(List list, Map messMap, String keyName, String valueName, boolean isStr){
if(ListUtil.isNull(list)){
logger.info("iii= list is null/empty. =iii");
return ;
}
if(MapUtils.isEmpty(messMap)){
logger.info("iii= messMap is null/empty. =iii");
return ;
}
if(keyName == null){
logger.info("iii= keyName is null. =iii");
return ;
} initmethodAccessMap();
Class clazz = list.get(0).getClass();
MethodAccess ma = getMethodAccess(clazz); String setValueMethodName = "set" + StrFormatUtil.captureName(valueName);
int setValueMethodIndex = ma.getIndex(setValueMethodName); String getKeyMethodName = "get" + StrFormatUtil.captureName(keyName);
int getKeyMethodIndex = ma.getIndex(getKeyMethodName); for(Object object : list){
Object keyValue = ma.invoke(object, getKeyMethodIndex, keyName);
Object value = messMap.get(keyValue);
if(value == null && isStr){
value = "";
}
ma.invoke(object, setValueMethodIndex, value);
} }
 /**
* 设置内容到对象中
* @param object 需要设置的内容
* @param fieldName 字段名
* @param fieldValue 设置的内容
*/
public static void setField(Object object, String fieldName, Object fieldValue){
if(object == null){
logger.info("iii= object is null. =iii");
return ;
}
if(fieldName == null){
logger.info("iii= fieldName is null. =iii");
return ;
}
if(fieldValue == null){
logger.info("iii= fieldValue is null. =iii");
return ;
} initmethodAccessMap();
Class clazz = object.getClass();
MethodAccess ma = getMethodAccess(clazz); String methodName = "set" + StrFormatUtil.captureName(fieldName);
int methodIndex = ma.getIndex(methodName);
ma.invoke(object, methodIndex, fieldValue);
}

批量填充的情况,每次装填信息前,只要获取主对象list,装填信息集合map,设置两个字段名,即可完成。

第一次写博客,写得不好多多包涵。后面会坚持写,力求写出好而美的文章。

基于reflectasm打造自己的通用bean工具的更多相关文章

  1. 基于tauri打造的HTTP API客户端工具-CyberAPI

    国庆长假和朋友聚会的时候,和朋友谈起最近这段时间捣鼓tauri,写了一个HTTP API客户端工具.『你写了这么多东西,其实有想过是为了啥不?』为了啥这是一个很大的命题,当初每个项目的时候都想过它应该 ...

  2. foy: 轻量级的基于 nodejs 的通用 build 工具

    npm 的 scripts 下写的命令太多就很容易很乱,各种第三方轮子都只能解决一部分问题,总感觉不是很好用,想找个类似 make 的工具只能找到 jake, 可是 jake 的 API 太老,居然很 ...

  3. 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 开源倾情奉献系列链接 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码 开源倾 ...

  4. 基于.NET打造IP智能网络视频监控系统

    开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码   开源倾情奉献系列链接 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码 开源倾情奉献:基于.NET打造 ...

  5. 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil

    封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil,代码比较简单,主要是把MongoTarget的配置.FileTarget的配置集成到类中,同时利用缓存依赖来判断是否需要重新创 ...

  6. liferay总结的通用的工具类

    在写增删改查的时候,自己动手写了几个通用的工具类,这几个通用的工具类也是基于API写的 第一个是liferay中的分页.跟我们做普通的web开发,分页是一样的首先需要建立一个分页的实体的类 packa ...

  7. 通用数据库管理工具DBeaver

    通用数据库管理工具DBeaver   在渗透测试中,用户往往需要管理很多数据库.这些数据库可能是渗透软件使用的(如Metasploit使用的Postgresql),也有目标主机的数据库(如网站的数据库 ...

  8. 智能家居巨头 Aqara 基于 KubeSphere 打造物联网微服务平台

    背景 从传统运维到容器化的 Docker Swarm 编排,从 Docker Swarm 转向 Kubernetes,然后在 Kubernetes 运行 SpringCloud 微服务全家桶,到最终拥 ...

  9. 基于SSM框架的JavaWeb通用权限管理系统

    - - ->关注博主公众号[C you again],获取更多IT资源(IT技术文章,毕业设计.课程设计系统源码,经典游戏源码,HTML网页模板,PPT.简历模板,!!还可以投稿赚钱!!,点击查 ...

随机推荐

  1. Java进阶(二十六)公司项目开发知识点回顾

    公司项目开发知识点回顾 前言 "拿来主义"在某些时候并不是最佳选择,尤其是当自己遇到问题的时候,毫无头绪. 在一次实验过程中,需要实现数据库的CRUD操作.由于之前项目开发过程中, ...

  2. Volley请求

    1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...

  3. 关于reverse_iterator

    这个reverse_iterator曾经搞得我头大,其对应的函数也是那么的可不理解...现在一切都好了. 对于left_null>1->2->3->4->right_nu ...

  4. 手把手教你打造一个心电图效果View Android自定义View

    大家好,看我像不像蘑菇-因为我在学校呆的发霉了. 思而不学则殆 丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力. 好了废话不说 ...

  5. AJAX+jQuery+ASP实现实时验证身份证信息是否已存在---人事系统

    很多时候在网站上注册时,我们会发现,注册表单通常需要检查用户名和电子邮件地址的可用性:从而确保用户之间不拥有相同的用户名和电子邮件地址:一些网站喜欢在用户提交填写的用户信息时,做信息可用性的检查,而一 ...

  6. 【一天一道LeetCode】#60. Permutation Sequence.

    一天一道LeetCode系列 (一)题目 The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and ...

  7. 【一天一道LeetCode】#43. Multiply Strings

    一天一道LeetCode系列 (一)题目 Given two numbers represented as strings, return multiplication of the numbers ...

  8. python的list

    1.定义list >>> li = ["a", "b", "mpilgrim", "z", " ...

  9. C++虚拟多重继承对象模型讨论

    C++虚拟多重继承对象模型讨论 作者:magictong 调试环境:Windows7VS2005 概述 记得刚开始写C++程序时,那还是大学时光,感觉这玩意比C强大多了,怎么就实现了多态,RTTI这些 ...

  10. /dev/null 2>&1的意思(可以直接参考shell重定向那篇,/dev/null是空设备)

    路还长 别太狂 以后指不定谁辉煌 2>&1 和 &> 的解释 Linux的IO输入输出有三类 Standard Input 代码 0 Standard Output 代码 ...