业务场景:

在很多的业务系统中,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. FreeMarker 生成Java、mybatis文件

    FreeMarker 生成Java.mybatis文件 将mysql数据库表通过FreeMarker生成对应的Java文件和对应的mybatis文件. FreeMarker是一款模板引擎: 即一种基于 ...

  2. iOS开发:创建真机调试证书步骤(还有一篇是真机测试步骤)(2015年)

    (关于真机测试步骤的blog:http://blog.csdn.net/hbblzjy/article/details/51680282) 1.首先打开苹果的开发者网站(https://develop ...

  3. #一周五# VS2015 CTP6, TFS2015 CTP1更新,老衣的开发工具汇总,2015 MVP 社区巡讲

    又到周五,这一周博主我工作效率极高,每天更新博客一篇,<快速创建网站>系列已经进程大半了,希望这个系列能够对大家有所帮助.今天周五了,博主要休息一下,就给大家唠叨一下这段时间都发生了什么. ...

  4. Java进阶(十三)servlet监听器

    servlet监听器 Listener是Servlet的监听器,它可以监听客户端的请求.服务端的操作等.通过监听器,可以自动激发一些操作,比如监听在线的用户的数量.当 增加一个HttpSession时 ...

  5. Android中使用SVG矢量图(一)

    SVG矢量图介绍 首先要解释下什么是矢量图像,什么是位图图像? 1.矢量图像:SVG (Scalable Vector Graphics, 可伸缩矢量图形) 是W3C 推出的一种开放标准的文本式矢量图 ...

  6. Android主题切换—夜间/白天模式探究

    现在市面上众多阅读类App都提供了两种主题:白天or夜间. 上述两幅图片,正是两款App的夜间模式效果,所以,依据这个功能,来看看切换主题到底是怎么实现的(当然现在github有好多PluginThe ...

  7. *** non-numeric second argument to `wordlist' function: ''. Stop错误解决办法

    PS: 解决办法搜集自:stackoverflow website:http://stackoverflow.com/questions/5677178/ndk-gdb-fails-with-mess ...

  8. linux内核算法---hex_to_bin分享

    这是我从内核抠出来的一段代码,用处就是传入一个字符,即可以用printf语句%d以十进制数的格式输出,同时也可以以%p地址的形式输出. 代码如下: #include <stdio.h> # ...

  9. 用C语言将一个数开根号后再取倒数的方法

    在上学的时候,曾经看过有人写过这样的算法,就是将一个数开根号后再取倒数的算法,我本人也觉得十分巧妙,于是就将它积累了下来,让我们来看看是怎么回事: #include <stdio.h> # ...

  10. web报表工具finereport常用函数的用法总结(数组函数)

    ADD2ARRAY ADDARRAY(array,insertArray, start):在数组第start个位置插入insertArray中的所有元素,再返回该数组. 示例: ADDARRAY([3 ...