业务场景:

在很多的业务系统中,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. Chapter 2 User Authentication, Authorization, and Security(6):服务器权限授予粒度

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/38867489,专题目录:http://blog.csdn.net/dba_huangzj ...

  2. Socket编程实践(6) --TCP服务端注意事项

    僵尸进程处理 1)通过忽略SIGCHLD信号,避免僵尸进程 在server端代码中添加 signal(SIGCHLD, SIG_IGN); 2)通过wait/waitpid方法,解决僵尸进程 sign ...

  3. spring mvc接收List集合、JUI传JSP List

    JUI页面是这样的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <div class=&quo ...

  4. UML之概述

              UML,英文名曰:Unified  Modeling Language,她还有个中文名字叫统一建模语言,简单的来说,她就是一种绘制软件蓝图的标准语言.她的表达能力特别强,可以描述开 ...

  5. Cocos2D中的ObjectAL简介

    Cocos2D包含ObjectAL音频库,可以回放音效和音乐. ObjectAL是一个建立在低级别OpenAL API上的库.OpenAL最擅长被用来播放短的音效(.wav,.caf,.aiff),并 ...

  6. OM模块功能&API详解

    (一)销售订单概述 1.1   与车间模块关系 当使用ATO类型订单时,订单管理模块会直接在车间模块中产生任务 1.2   与库存模块关系 在销售订单中使用的物料,单位等信息均来自库存模块,在订单执行 ...

  7. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. Linux常用命令(第二版) --网络通信命令

    网络通信命令 1.write /usr/bin/write 格式: write [用户名] #用于向用户发送信息,前提是这个用户已经登录到了这台服务器主机,不然的话,也没有办法给他留言,所以,writ ...

  9. android 防止反编译的若干方法

    第一种方式:混淆策略 混淆策略是每个应用必须增加的一种防护策略,同时他不仅是为了防护,也是为了减小应用安装包的大小,所以他是每个应用发版之前必须要添加的一项功能,现在混淆策略一般有两种: 对代码的混淆 ...

  10. 【LaTeX排版】LaTeX论文排版<一>

    本文及接下来的几篇文章主要讲关于毕设论文的排版. 1.论文的整体构架     学校规定论文字数不得少于15000:说明论文属于中篇论文.一般来说,中长篇论文采用book文类,短篇论文采用article ...