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

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

### 这次的分享主题是日常开发中,关于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. Spring Boot 整合 Shiro实现认证及授权管理

    Spring Boot Shiro 本示例要内容 基于RBAC,授权.认证 加密.解密 统一异常处理 redis session支持 介绍 Apache Shiro 是一个功能强大且易于使用的Java ...

  2. 关于使用 AJax 生成Form表单,且表单提交需要验证,验证实效的解决方法

    @Ajax.ActionLink("添加", "AddUser",new AjaxOptions() {InsertionMode = InsertionMod ...

  3. 算法学习笔记,几个简单的Demo

    算法初学的一些心得 前言:现在工作也快一年多了,有时间下班回家会学学算法,陆陆续续也接触了一些 貌似我知道的就冒泡排序其他的都不是很了解 最近买了一本书,边学边记录吧! 一些常用的方法 暴力破解 下面 ...

  4. 洛谷P2299 Mzc和体委的争夺战 题解

    题目 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道).但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来与mzc争夺男家丁. mzc很生气,决定与其决斗,但cat的体 ...

  5. 个人永久性免费-Excel催化剂功能第103波-批量打开多文件或多链接

    有时简单的东西,却带来许多的便利,为了让大家可以记住并容易找寻到此功能,也将这么简单的功能归为一波,反正已经100+波了,也无需为了凑功能文章而故意罗列一些小功能带忽悠性地让人觉得很强大. 使用场景 ...

  6. RabbitMQ延迟消息的延迟极限是多少?

    之前在写Spring Cloud Stream专题内容的时候,特地介绍了一下如何使用RabbitMQ的延迟消息来实现定时任务.最近正好因为开发碰到了使用过程中发现,延迟消息没有效果,消息直接就被消费了 ...

  7. 基于Ajax的前后端分离

    这种开发模式可以称为SPA (Single Page Application 单页面应用)时代. 这种模式下,前后端的分工非常清晰,前后端的关键协作点是 Ajax 接口.看起来是如此美妙,但回过头来看 ...

  8. Gridea+GitHub搭建个人博客

    某日闲余时间看到一篇介绍Gridea博客平台的文章,大概看了一下觉得此平台还不错,随即自己进入Gridea官网瞅了瞅.哇,这搭建过程也太简单了吧,比Hexo博客搭建要容易很多,而且还有后台管理客户端, ...

  9. LongAdder和AtomicLong性能对比

    jdk1.8中新原子操作封装类LongAdder和jdk1.5的AtomicLong和synchronized的性能对比,直接上代码: package com.itbac.cas; import ja ...

  10. 一文带你彻底理解 JavaScript 原型对象

    一.什么是原型 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承. 1.1 函数的原型对象 在JavaScript中,我们创建一个函数A(就是声明一个函数), 那 ...