文档章节

如何利用AOP将对象数据字典字段code转换name输出前端展示

随风所欲
 随风所欲
发布于 2015/12/25 15:01
字数 947
阅读 196
收藏 3
  • 首先编写自定义注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Dict {
	String value() default "";
}

  • 然后将注解绑在需要转换的对象字段上并指明该字段所属码表的父级code

@Dict("008")
private String countStatus;

  • 接着编写aop类设定查询方法的切入点

@Aspect
@Configuration
public class DataDictionaryHandleAOP {
	@Autowired
	//数据字典处理工具类
	private DataDictionaryUtil dataDictionaryUtil;
	//设定切入点
	@Pointcut("execution(* com.bjhy.platform.sw.*.service.impl.*.findByPage(..)) || execution(* com.bjhy.platform.sw.*.service.impl.*.findByPage_*(..))")
	private void anyMethod(){};
	
	//切入方式为后切入
	@AfterReturning("anyMethod() && args(pageInfo)")
	public void doAfter(PageInfo<?> pageInfo){
		System.out.println("AOP数组字典code转name--start "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		int count = 0;
		//获取数据集
		List<?> list = pageInfo.getPage().getContent();
		if(list!=null&&list.size()>0){
			long startD = new Date().getTime();
			//初始中央平台获取class转换所需的码表集合
			dataDictionaryUtil.initData(list.get(0).getClass());
			//开始转换
			dataDictionaryUtil.handDictionaryCodeToCodeName(list);
			count  = (int) (new Date().getTime() - startD);
		}
		System.out.println("AOP数组字典code转name--end"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		System.out.println("耗时:"+count+" ms");
	}
	
}

  • 最后通过反射编写转换代码,特别处理部分@OneToOne链表对象

@Component
public class DataDictionaryUtil {
	@Reference
	private SystemCodeService systemCodeService;//cas系统获取数据字典服务
	@Reference
	private OrganizationService organizationService;//cas系统获取组织机构服务
	//数据字典
	private static List<SystemCode> dictList = new ArrayList<SystemCode>();
	//组织机构字典
	private static List<OrganizationInfo> orgList = new ArrayList<OrganizationInfo>();
	//需要转化的字段名
	private static String fieldNames = "";
	//已经获取的数据字典记录,避免重复去cas系统获取
	private static Map<String, String> codeRecord = new HashMap<String, String>();
	
	/**
	 * 根据clzz初始将要转化的字典数据
	 * @param clzz 需要转换的对象class
	 */
	public <T> void initData(Class<T> clzz){
		clear();
		initDictionary(clzz);
	}
	
	public void clear(){
		fieldNames = "";
	}
	
	public <T> void initDictionary(Class<T> clzz){
		Field[] fields = clzz.getDeclaredFields();
		for (Field field : fields) {
			Class c = field.getType();
			//判断字段否是对象
			if(null!=c.getClassLoader()){
				//递归获取需要转换的字段
				initDictionary(c);
			}else{
				if(field.isAnnotationPresent(Dict.class)){
					fieldNames += clzz.getSimpleName()+"."+field.getName()+",";
					Dict dict = field.getAnnotation(Dict.class);
					//判断是否已经获取过该code的字典数据 避免重复获取
					if(codeRecord.get(dict.value()) == null){
						List<SystemCode> list = systemCodeService.getChildrenByCode(dict.value());
						if(list!=null&&list.size()>0){
							dictList.addAll(list); 
							//记录已经获取的字典code
							codeRecord.put(dict.value(), dict.value());
						}
					}
				}else if(field.isAnnotationPresent(Org.class)){
					fieldNames += clzz.getSimpleName()+"."+field.getName()+",";
					Org org = field.getAnnotation(Org.class);
					if(codeRecord.get(org.value()) == null){
						List<OrganizationInfo> list = organizationService.getChildrenByType(org.value());
						if(list!=null&&list.size()>0){
							orgList.addAll(list);
							codeRecord.put(org.value(), org.value());
						}
					}
				}
			}
		}
	}
	/**
	 * 将指定数据内凡是对象标注有@dict @org 注解的字段转化为对应数据字典的codeName)
	 * @param datalist 数据集合(一般为分页查询后的pageInfo.getPage().getContent()数据)
	 * @return 返回List<Object> 
	 */
	public <T> List<Object> handDictionaryCodeToCodeName(List<?> datalist){
		System.out.println("需要转换的字段为:"+fieldNames);
		if(StringUtils.isNotEmpty(fieldNames)){
			String[] fNames = fieldNames.split(",");
			for (Object object : datalist) {
				codeToName(fNames, object);
			}
		}
		return (List<Object>) datalist;
	}
	
	public void codeToName(String[] fNames,Object object){
		String classFieldName = "";
		Class clzz = object.getClass();
		Field[] fields = clzz.getDeclaredFields();
		for (int i = 0; i < fNames.length; i++) {
			for (Field field : fields) {
				Class c = field.getType();
				//是否是对象
				if(null!=c.getClassLoader()){
					//只统计一次
					if(i==0){
						classFieldName += field.getName()+",";
					}
				}else{
					String[] n = fNames[i].split("\\.");
					if(clzz.getSimpleName().equals(n[0])&&field.getName().equals(n[1])){
//						System.out.println("开始转换字段:"+fNames[i]);
						try {
							field.setAccessible(true);
							String val = (String) field.get(object);
							if(field.isAnnotationPresent(Dict.class)){
								for (SystemCode code : dictList) {
									if(code.getCode().equals(val)){
										field.set(object, code.getCodeName());
										break;
									}
								}
							}else if(field.isAnnotationPresent(Org.class)){
								for (OrganizationInfo org : orgList) {
									if(org.getOrgCode().equals(val)){
										field.set(object, org.getOrgName());
										break;
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
						break;
					}
				}
			}
		}
		String[] classFieldNames = classFieldName.split(",");
		for (String fieldName : classFieldNames) {
			try {
				if(StringUtils.isNotEmpty(fieldName)){
					Field classField = clzz.getDeclaredField(fieldName);
					classField.setAccessible(true);
					if(null!=classField.get(object)){
						codeToName(fNames, classField.get(object));
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		
	}

}


© 著作权归作者所有

共有 人打赏支持
随风所欲
粉丝 2
博文 9
码字总数 7237
作品 0
成都
私信 提问
词嵌入向量WordEmbedding的原理和生成方法

WordEmbedding 词嵌入向量(WordEmbedding)是NLP里面一个重要的概念,我们可以利用WordEmbedding将一个单词转换成固定长度的向量表示,从而便于进行数学处理。本文将介绍WordEmbedding的使用方...

JackMeGo
2017/12/15
0
0
input搜索下拉提示框,支持拼音检索、过滤、级联、自定义数据源的ajax异步下拉展示

为解决大数据量下拉字典效率及操作问题,整理出通用的数据字典模块,所有字典数据可在数据库维护,在大数据量时采用分页下拉的展示方式,同时支持拼音简拼搜索,代码项、代码值搜索等,支持无...

神话无名
06/07
0
0
功能表单之树形选择字段类型的高级使用——JEPLUS软件快速开发平台

JEPLUS功能表单之树形选择字段类型的高级使用 JEPLUS功能表单中树形选择字段类型的目标字段在开发过程中还有一些高级配置和高级应用,如果知晓怎么配置也许能解决我们系统开发过程的大问题,...

JEPLUS
06/13
0
0
【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类

背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题。我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题。视图和控制器相关的内存泄露,几乎都不存在了。后...

ios122
2017/11/23
0
0
iOS开发·runtime+KVC实现多层字典模型转换(多层数据:模型嵌套模型,模型嵌套数组,数组嵌套模型)

本文实验Demo传送门:DictToModelDemo 前言:将后台JSON数据中的字典转成本地的模型,我们一般选用部分优秀的第三方框架,如SBJSON、JSONKit、MJExtension、YYModel等。但是,一些简单的数据...

陈满iOS
05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 安装PHP5和PHP7

安装PHP5 下载解压二进制包 [root@test-a src]# cd /usr/local/src/[root@test-a src]# wget http://cn2.php.net/distributions/php-5.6.32.tar.bz2[root@test-a src]# tar jxvf php-5.6......

野雪球
今天
3
0
windows上类似dnsmasq的软件Dual DHCP DNS Server

官网地址:http://dhcp-dns-server.sourceforge.net/官网定向的下载地址:https://sourceforge.net/projects/dhcp-dns-server/files/ 设置参考地址:http://blog.51cto.com/zhukeqiang/18264......

xueyuse0012
今天
3
0
LinkedHashMap源码解析

前言 HashMap中的元素时无序的,也就是说遍历HashMap的时候,顺序和放入的顺序是不一样的。 如果需要有序的Map,就可以采用LinkedHashMap. LinkedHashMap通过维护一个包含所有元素的双向链表,...

grace_233
今天
3
0
初识flask

文档 0.10.1版本 http://www.pythondoc.com/flask/index.html 1.0.2版本 https://dormousehole.readthedocs.io/en/latest/ 安装flask $ pip3 install flaskCollecting flask Downloading......

yimingkeji
昨天
5
0
Akka系统《sixteen》译

Actor是一个封装状态(state)和行为(behavior)的对象,它们只通过交换消息通信(放入收件人邮箱的邮件)。从某种意义上说,Actor是最严格的面向对象编程形式,但它更适合将他们视为人:在与Act...

woshixin
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部