如何从0到1的构建一款Java数据生成器-第二章
前提
在上一章我们提到了并且解决了几只拦路虎,承上启下,下面我们一起来实现一款数据生成器。
对外API
/**
* @description: 本地数据生成API
* @author: peter
* @create: 2020-10-02 15:09
**/
public class FastData<T> {
private T o;
private DataFactory dataFactory = DataFactory.getDataFactory(); //数据工厂 /**
* 生成单个对象
* @param clazz 欲生成的对象类型
* @return Data 生成的数据
*/
public T build(Class clazz){
try {
o = (T)clazz.newInstance();
}catch (Exception e) {
e.printStackTrace();
}
Object entity = dataFactory.build(o);
return (T)entity;
} /**
* 生成多个对象
* @param claszz 欲生成的对象类型
* @param size 欲生成数量
* @return 生成的对象数据集合
*/
public List<T> builds(Class claszz,int size){
List<T> resultList = new ArrayList<T>();
for(int i = 0; i < size; i++){
resultList.add(build(claszz));
}
return resultList;
}
}
两个方法:build(Class clazz) ,builds(Class claszz,int size)
我们来对build方法进行分析,在FastData类中,我们定义了一个泛型的对象o, 此对象的存在格外重要,在build方法中,o = (T)clazz.newInstance() 给此对象赋值一个实例,意义是为了后续能够反射出泛型对象内的属性,交由DataFactory数据工厂进行构建,dataFactory.build(o) 将返回一个已经设置了对应属性值的Object, 此Object实际上是泛型对象的装箱结果,所以 return (T)entity 此处在拆箱成泛型T,没有任何问题。
DataFactory 数据工厂
/**
* @description: 数据工厂
* @author: peter
* @create: 2020-10-02 15:13
**/
public class DataFactory {
private static DataFactory dataFactory = new DataFactory();
private ValueGeneration valueGeneration = new ValueGeneration(); //值生成器
private DataFactory(){ } public static DataFactory getDataFactory(){
return dataFactory;
} /**
* 构建数据对象
* @param o 实例类型
* @return 生成后的对象
*/
public Object build(Object o){
Object entity = null;
try {
entity = o.getClass().newInstance();//创建一个新对象
Map<String, Field> fieldMap = ObjectUtil.getFields(o);//获取对象的属性
for(String fieldName : fieldMap.keySet()){
Object value = valueGeneration.generation(fieldMap.get(fieldName).getType(),fieldMap.get(fieldName)); //生成对应类型的值
fieldMap.get(fieldName).set(entity,value);//把值设置到新对象
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} return entity; //返回新对象
} }
本类其他地方都很明了,但是有个地方需要说明一下,可能有的朋友会不解,valueGeneration.generation(fieldMap.get(fieldName).getType(),fieldMap.get(fieldName))
此处将fieldMap.get(fieldName)传到valueGeneration,为何还要传fieldMap.get(fieldName).getType(),这不是多次一举吗?其实不然,这里跟架构设计有关系,后续说明。
ObjectUtil 对象工具
/**
* @description: 对象工具
* @author: peter
* @create: 2020-10-02 15:14
**/
public class ObjectUtil {
//是否开启缓存
private static boolean isCache = Boolean.valueOf(PropertiesUtil.getValue("true","com.config.cache")); /**
* 属性Map
* @param o 欲反射的对象
* @return 对象的属性Map<属性名,属性>
*/
public static Map<String, Field> getFields(Object o){
Map<String,Field> fieldMap = null;
if(isCache){//是否开启缓存
//是否存在缓存
if(LocalCache.fieldMapBuffer.get(o.getClass().getName()) != null){
//返回缓存中的Map
return LocalCache.fieldMapBuffer.get(o.getClass().getName());
}else{
//反射
fieldMap = reflectionObject(o);
//添加到缓存
LocalCache.fieldMapBuffer.put(o.getClass().getName(),fieldMap);
}
}else{
fieldMap = reflectionObject(o);//反射
}
return fieldMap;
} private static Map<String,Field> reflectionObject(Object o){
Map<String,Field> fieldMap = new HashMap<String, Field>();
Field[] fields = o.getClass().getDeclaredFields();
for(Field field : fields){
fieldMap.put(field.getName(),field);
}
return fieldMap;
}
}
反射会比较消耗资源,此处做一个缓存机制,小工具也用不上Redis之类的专业内存库,自己写个Map做缓存,且使用者也应该只有极少数会在程序执行过程中更改类的属性列表,毕竟这不是一件简单的事情。
LocalCache 本地缓存
/**
* @description: Cache
* @author: peter
* @create: 2020-10-03 17:49
**/
public class LocalCache {
//序列缓存
public static Map<String,Integer> sequenceBuffer = new HashMap<String, Integer>();
//对象属性缓存
public static Map<String, Map<String, Field>> fieldMapBuffer = new HashMap<String, Map<String, Field>>();
}
此类中的序列缓存后续说明,有大用处。
在ObjectUtil中,还存在 PropertiesUtil.getValue("true","com.config.cache") 这样一句代码,此类内容如下:
PropertiesUtil 配置工具
/**
* @description: Properties 配置工具
* @author: peter
* @create: 2020-10-02 16:22
**/
public class PropertiesUtil {
private static PropertiesScan propertiesScan = PropertiesScan.getPropertiesScan(); /**
* 获取配置的值
* @param defalut 默认值
* @param propertiesKey key
* @return 配置值
*/
public static String getValue(String defalut,String propertiesKey){
String result = defalut;
if(null != propertiesScan.getValue(propertiesKey)){
result = propertiesScan.getValue(propertiesKey).toString();
}
return result;
} public static int getValueByInt(int defalut ,String propertiesKey){
int result = defalut;
if(null != propertiesScan.getValue(propertiesKey)){
result = Integer.parseInt(propertiesScan.getValue(propertiesKey).toString());
}
return result;
}
}
PropertiesScan
/**
* @description: 配置扫描
* @author: peter
* @create: 2020-10-01 17:54
**/
public class PropertiesScan {
private static PropertiesScan propertiesScan = new PropertiesScan();
private static String propertiesPath = null;
private static Properties properties = null;
private PropertiesScan(){ } public static PropertiesScan getPropertiesScan(){
propertiesScan.load();
return propertiesScan;
} private void load(){
properties = new Properties();
try {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("jfd.properties");
properties.load(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public Object getValue(String key){
return properties.get(key);
} }
以上均为后续的数据生成做准备,为了各位更好的观看,此篇到此为止,下一章简述数据生成部分,填上之前埋下的2个坑。精彩继续。
如何从0到1的构建一款Java数据生成器-第二章的更多相关文章
- 如何从0到1的构建一款Java数据生成器-第一章
前提 某天晚上老夫在神游时,想起白天公司同事说起的问题,这老表抱怨使用mysql生成大批的随机测试数据太过麻烦,问大家有没有好的工具推荐,老夫对这种事情当然不关心,毕竟我也不知道. 秉承着不懂就要问, ...
- Laxcus大数据管理系统2.0(5)- 第二章 数据组织
第二章 数据组织 在数据的组织结构设计上,Laxcus严格遵循数据和数据描述分离的原则,这个理念与关系数据库完全一致.在此基础上,为了保证大规模数据存取和计算的需要,我们设计了大量新的数据处理技术.同 ...
- 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序
面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...
- 三、使用Maven构建简单的java项目
前边,我刚搭建了Maven环境,还有给大家推荐了学习资源,这个小节,我们来就来,,简单的玩玩maven. 1.所需工具: 1.Eclipse 2.apache-maven-3.3.9 3. ...
- Ant构建与部署Java项目---入门
原文地址:http://tech.it168.com/j/2007-11-09/200711091344781.shtml Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建 ...
- 【原创】构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施
原文:[原创]构建高性能ASP.NET站点 第六章-性能瓶颈诊断与初步调优(下前篇)-简单的优化措施 构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施 前言:本篇 ...
- 【原创】构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测CLR性能
原文:[原创]构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)-托管资源优化-监测CLR性能 构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测C ...
- 微信小程序教学第二章:小程序中级实战教程之预备篇 - 项目结构设计 |基于最新版1.0开发者工具
iKcamp官网:http://www.ikcamp.com 访问官网更快阅读全部免费分享课程:<iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享>. ...
- Gradle入门(3):构建第一个Java项目
Gradle插件通过引入特定领域的约定和任务来构建你的项目.Java插件是Gradle自身装载的一个插件.Java插件提供的基本功能远比源代码编译和打包多.它为你的项目建立了一个标准的项目布局,并确保 ...
随机推荐
- centos开放指定端口
1.开启防火墙 systemctl start firewalld 2.开放指定端口 firewall-cmd --zone=public --add-port=1935/tcp ...
- Jenkins下Vue自动部署(二)
1Jenkins配置 获取首次密码 sudo docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword 2 2.1J ...
- 【原创】解BUG-xenomai内核与linux内核时间子系统之间存在漂移
版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 一.问题起源 何为漂移?举个例子两颗32.768kH ...
- 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...
- 深入理解xLua热更新原理
热更新简介 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种热更新 ...
- oracle之二ASM 管理
Oracle ASM 管理(PPT-II:602-636) 16.1 什么是ASM 自动存储管理即ASM(Automatic Storage Management),是Oracle提供的一项管理磁盘的 ...
- Kafka 【入门一篇文章就够了】
初识 Kafka 什么是 kafka Kafka 是由 Linkedin 公司开发的,它是一个分布式的,支持多分区.多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的基于发布订 ...
- JavaScript 流程控制-循环
1.循环 循环目的 在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句 JS中的循环 在JS中,主要有三种类型的循环语句: for循环 while循环 do.. ...
- Docker容器监控(十)
docker自带的监控命令 docker自带了三个监控命令即ps, top, stats ps docker ps 可以帮助我们很快的了解当前正在运行的容器 -a:会显示已经停掉的容器 [root ...
- Redis的五大数据类型以及key的相关操作命令
Redis的五大数据类型 redis的数据都是以key/value存储,所以说,五大类型指的是value的数据类型 String 字符串,作为redis的最基本数据类型 redis中的string类型 ...