> 好久没有写技术文章了,那就重新捡起来,从今天开始,分享这段时间的收获吧

------------
> ## 其实很多时候,我们只需要鱼,而不是渔,呐,给你鱼。

### 这次的分享主题是日常开发中,关于ID转Name的问题,常见的处理就两个方案:
1. 后端直接转换,前端只负责显示
2. 前端转换(常见的vue 过滤器等),后台不做任何处理

那么在什么时候应该选择什么方案呢,一般来讲会根据待转换数据的数量来决定,5k条以内两个方案都没有问题,但是数据量太大了之后
再选择前端转换的方案就会出现明显的卡顿,和加载缓慢的问题,所以会选择后台来处理,今天就给大家一个做好的鱼,拿好了,开始发了
哈~
![file](https://img2018.cnblogs.com/blog/1776459/201908/1776459-20190823133930698-1355856458.jpg)
如图,思路很简单,把工具当做一个容器,容器只提供两个方法:
1. 方法一用来接收数据源;
2. 方法二用来id转换成name

> 先看使用的例子吧:

### 带转换实体:

```
import java.util.Date;

@Data
public class DemoEntity {

//默认转换模式,转换到新的字段,默认字段名:原属性名+“_str”
@IdToName
private Integer aId;

//转换覆盖原属性
@IdToName(NewField = false)
private Integer bId;

//转换到新的字段,新字段名为 "cId_str"
@IdToName(Alias = "cId_str")
private Integer cId;

//格式化时间,默认格式为 "yyyy-MM-dd"
@IdToName(DateFormat = true)
private Date startTime;

//格式化时间,格式为 "yyyy-MM-dd HH:mm:ss"
@IdToName(DateFormat = true, FormatStr = "yyyy-MM-dd HH:mm:ss")
private Date endTime;

}
```
### 测试方法:

```
public static void main(String[] args) {
//1、准备数据源:
Map dataSource = new HashMap(1 list = new ArrayList();
list.add(demoEntity);

//4、转换实体
System.out.println(idToNameUtil.transportIdToName(list).toString());
}
```
### 测试结果:
[{aId_str=1a名称, startTime_str=2019-08-23, cId_str=3c名称, startTime=Fri Aug 23 11:24:30 CST 2019, endTime=Fri Aug 23 11:24:30 CST 2019, endTime_str=2019-08-23 11:24:30, AId=1, BId=2, bId=2b名称, CId=3}]

使用很简单,看完例子应该就可以上手了,尝试着写下吧;
**对了,转换10w数据的耗时在100ms+**

---

**下面就是具体的实现,更简单,一个自定义注解一个工具类,导入到项目就可以直接开始使用**:
1. 自定义注解:

```
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface IdToName {

/**
* 是否生成一个新的字段
*
* @return
*/
boolean NewField() default true;

/**
* 字段别名
*
* @return
*/
String Alias() default "";

/**
* 是否格式化时间
*
* @return
*/
boolean DateFormat() default false;

/**
* 时间格式(d:yyyy-MM-dd | s:yyyy-MM-dd HH:mm:ss)
*
* @return
*/
String FormatStr() default "yyyy-MM-dd";
}
```
2. 转换工具类:

```
import com.google.common.collect.Maps;
import com.hd.bizexpansion.annotation.IdToName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* id转name工具类
*
* @author wang_yw
* @version 0.1
*/
@Component
public class IdToNameUtil {

private final Logger logger = LoggerFactory.getLogger(IdToNameUtil.class);

private Map sourceData = new HashMap();

/**
* 导入数据源
*
* @param sourceDataItem
*/
public void importSourceData(Map sourceDataItem) {
this.sourceData.putAll(sourceDataItem);
}

/**
* 转换方法
*
* @param items
* @return
*/
public List transportIdToName(List items) {
SimpleDateFormat sdf_d = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf_s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

if (this.sourceData.isEmpty() || items == null || items.isEmpty()) {
logger.warn("数据源为空,或者原数据为空");
}

//提前初始化结果集,长度等于参数数组避免长度自增浪费资源
List results = new ArrayList(items.size());

//遍历参数对象,开始id-name的翻译
for (Object object : items) {

Map item_map = this.beanToMap(object);
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {

//如果包含注解进行处理
if (field.isAnnotationPresent(IdToName.class)) {
IdToName idToName = field.getAnnotation(IdToName.class);
field.setAccessible(true);
try {
if (field.get(object) == null) {
continue;
}

//类属性别名
String alias = idToName.Alias();
//新属性名
String newFieldName = StringUtils.isEmpty(alias) ? field.getName() + "_str" : alias;

//如果是时间需要格式化
if (idToName.DateFormat()) {
if ("yyyy-MM-dd".equals(idToName.FormatStr())) {
item_map.put(newFieldName, sdf_d.format((Date) field.get(object)));
} else if ("yyyy-MM-dd HH:mm:ss".equals(idToName.FormatStr())) {
item_map.put(newFieldName, sdf_s.format((Date) field.get(object)));
}
continue;
}

if (idToName.NewField()) {
item_map.put(newFieldName, sourceData.get(field.get(object)));
} else {
item_map.put(field.getName(), sourceData.get(field.get(object)));
}

} catch (IllegalAccessException e) {
e.printStackTrace();
}

}
}
results.add(item_map);
}

return results;
}

/**
* 对象转map
*
* @param bean
* @return
*/
private Map beanToMap(Object bean) {
Map map = Maps.newHashMap();
if (bean != null) {
BeanMap beanMap = BeanMap.create(bean);
for (Object key : beanMap.keySet()) {
map.put(String.valueOf(key), beanMap.get(key));
}
}
return map;
}

}
```

其实很多时候,我们只需要鱼,而不是渔,呐,给你鱼。
TO BE CONTINUE !

ID转名称到手方案01的更多相关文章

  1. Atitit.软件命名空间  包的命名统计 及命名表(2000个名称) 方案java package

    Atitit.软件命名空间  包的命名统计 及命名表(2000个名称) 方案java package 1. 统计的lib jar 列表1 2. Code3 3. 常用包名按找字母排序(2000个)4 ...

  2. SQL-29 使用join查询方式找出没有分类的电影id以及名称

    题目描述 film表 字段 说明 film_id 电影id title 电影名称 description 电影描述信息 CREATE TABLE IF NOT EXISTS film ( film_i ...

  3. 获取设备 ID 和名称

    获取设备 ID 和名称 .NET Framework 3.5   其他版本   更新:2007 年 11 月 要获取设备的名称,请使用 Dns.GetHostName 属性.通常情况下,默认名称为“P ...

  4. Windows Store 应用获得设备 ID 的几种方案

    本文为个人博客备份文章,原文地址: http://validvoid.net/solutions-get-device-id-for-uwp/ 通过生成唯一的设备 ID 进行数据统计是应用开发中一个非 ...

  5. 黄聪:wordpress如何获取当前分类页面的ID、名称、别名(slug)

    <? global $wp_query; $cat_ID = get_query_var('cat'); $category = get_category($cat_ID); echo $cat ...

  6. ECSHOP在商品详细页面上获取该商品的顶级分类id和名称

    在 goods.php 文件, 找到 $smarty->assign('goods', $goods); 在它上面增加下面代码: 方法一: $cat_arr = get_parent_cats( ...

  7. sql 针对多个id或名称的分割和组合

    开发中经常遇到把多个id拼接在一起符号隔开传入数据库,那拆分呢就是个大事 SELECT nPushID INTO #temp FROM Table1 ), nCoulmn) SELECT * FROM ...

  8. Vijos 1025 小飞侠的游园方案 0-1背包

    描述 经过抽签选择,小智将军第一个进入考场. 菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!! 小智:--(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么 ...

  9. ID生成器之——别人家的方案and自家的方案

    “叮咚,叮咚……”,微信提示音一声接一声,声音是那么的频繁,有妖气,待俺去看一看. 这天刚吃完午饭,打开微信,发现我们的技术讨论组里有 100 多条未读消息,心想,是不是系统出问题了?怎么消息那么频繁 ...

随机推荐

  1. something good

    CF292A CF304B CF383A CF409D CF409F CF632A CF652B CF656A CF656B CF656D CF659A CF678A CF697A CF735D CF ...

  2. 高德网络定位之“移动WiFi识别”

    导读随着时代的发展,近10年来位置产业蓬勃发展,定位能力逐渐从低精度走向高精度,从部分场景走向泛在定位.设备和场景的丰富,使得定位技术和能力也不断的优化更新.定位能力包括GNSS.DR(航迹推算).M ...

  3. struct模块(用于对象的压缩)

    6.27自我总结 struct模块 1.struct模块中的函数 函数 return explain pack(fmt,v1,v2-) string 按照给定的格式(fmt),把数据转换成字符串(字节 ...

  4. C#5.0新增功能01 异步编程

    连载目录    [已更新最新开发文章,点击查看详细] 如果需要 I/O 绑定(例如从网络请求数据或访问数据库),则需要利用异步编程. 还可以使用 CPU 绑定代码(例如执行成本高昂的计算),对编写异步 ...

  5. 脑裂是什么?Zookeeper是如何解决的?

    什么是脑裂 脑裂(split-brain)就是"大脑分裂",也就是本来一个"大脑"被拆分了两个或多个"大脑",我们都知道,如果一个人有多个大 ...

  6. linux初学者-常用基本命令篇

    linux系统中有着许许多多的命令,并且软件也有可能自带命令,要想全部了解这些命令是很困难的,但是有一些基本命令是在平时的学习工作中应用的很广泛的.以下简要介绍几种linux系统中的常用命令. 1.m ...

  7. jQuery入门一(jQuery下载以及基本语法)

    1. jQuery简介 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是 ...

  8. Apache SSI 远程命令执行漏洞复现

    Apache SSI 远程命令执行漏洞复现 一.漏洞描述 当目标服务器开启了SSI与CGI支持,我们就可以上传shtml,利用<!--#exec cmd=”id” -->语法执行命令. 使 ...

  9. 使用secureCRT上传下载

    secureCRT 的 下载 http://pan.baidu.com/s/1c1Mz1ks 下载完成后,输入yum install lrzsz,安装这个东西, 然后就可以直接在secureCRT中输 ...

  10. 基于高德开放平台的 NODE 天气信息组件

    看看了画在手上的Armani手表,马上就快到了下班的时间了,心里总觉的空唠唠的, 好像空缺了什么一样,仔细的想了一想,微微叹了一口气,觉得是时候在这里和大家分享一下原因了........ 首先: ## ...