业务场景:

在很多的业务系统中,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. leetcode 226 Invert Binary Tree 翻转二叉树

    大牛没有能做出来的题,我们要好好做一做 Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Tri ...

  2. NSData 与 struct 以及XML的转换。

    在做OC与C++ 混编的时候,我们可能会用到struct 与NSData的相互转换.在这里做一个记录 1.struct转换为NSData 例如如下的struct: struct tagPackageH ...

  3. JSP连接access数据库

    一个用jsp连接Access数据库的代码. 要正确的使用这段代码,你需要首先在Access数据库里创建一username表,表里面创建两个字符型的字段,字段名分别为:uid,pwd,然后插入几条测试数 ...

  4. MySQL学习笔记_6_SQL语言的设计与编写(下)

    SQL语言的设计与编写(下) --SELECT查询精讲 概要: SELECT[ALL | DISTINCT] #distinct 明显的,清楚的,有区别的 {*|table.*|[table.]fie ...

  5. memcached /usr/local/memcached/bin/memcached: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory

    启动memcached的时候发现找不到libevent的库,这是memcache的默认查找路径不包含libevent的安装路径,所以要告诉memcached去哪里查找libevent. 操作命令如下: ...

  6. 【一天一道LeetCode】#54. Spiral Matrix

    一天一道LeetCode系列 (一)题目 Given a matrix of m x n elements (m rows, n columns), return all elements of th ...

  7. Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示

    Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示 今天项目中要实现一个天气的预览,加载的信息很多,字段也很多,所以理清了一下思路,准备独立出来写一个总结,这样对大家 ...

  8. Java之美[从菜鸟到高手演变]之设计模式四

    在阅读过程中有任何问题,请及时联系:egg. 邮箱:xtfggef@gmail.com 微博:http://weibo.com/xtfggef 转载请说明出处:http://blog.csdn.net ...

  9. How Many Processes Should Be Set For The Receiving Transaction Manager (RTM)

    In this Document   Goal   Solution   References APPLIES TO: Oracle Inventory Management - Version 10 ...

  10. netty对http协议解析原理解析

    本文主要介绍netty对http协议解析原理,着重讲解keep-alive,gzip,truncked等机制,详细描述了netty如何实现对http解析的高性能. 1 http协议 1.1 描述 标示 ...