背景

回想平时我们测试,需要数据就在数据库一顿猛操作也没达到所谓的乱数假文,但是Faker很好的为我们解决了这个问题,伪造的数据接近真实数据。但是我们也不能每次都去一个一个数据的生成,这样会叠加代码量,工作量也增加了,于是写了一个工具类,将faker相关的方法以及方法需要的参数和参数类型存入了数据库中,前端只要配置好相对应的数据就能生成伪造数据
githup地址

技术点

泛型+反射

Faker

基本用法
用法为:Faker.**.**
Faker faker = Faker.instance(Locale.CHINA);//.instance(Locale.CHINA)指定为中文
//默认英语,如下:
//Faker faker = new Faker();
//生成数据(生成随机电话号码)
//faker.phoneNumber().phoneNumber();
System.err.println("生成的随机电话号码为:"+faker.phoneNumber().phoneNumber());

Faker支持多种语言,80+个基础方法,约500种假数据类型(常用的有320种左右,记不清楚了,写入数据库就知道了),详情请看githup地址

控制台输出结果
生成的随机电话号码为:11132037344
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

maven 依赖

<dependency><groupId>com.github.javafaker</groupId><artifactId>javafaker</artifactId><version>1.0.2</version>
</dependency>

数据库表结构

数据库字段以及字段类型由于是测试,可根据实际需求修改。

utilFaker,主要用于存入Faker一级二级方法(faker.phoneNumber().cellPhone())一级为phoneNumber()二级为cellPhone()

util_faker_parameterinfo主要是存入最终方法的参数以及参数类型
如faker.number().randomDouble(int maxNumberOfDecimals, int min, int max)三个int类型的参数,参数主要是设置默认参数

JAVA实现

MockItem参数类(包含调用的方法,参数以及输出时参数对应的key)

@Data
public class MockItem{/*** @ 名称对应的faker一级方法.二级方法(number.randomDigit)*/private  String methodNames;/*** @ 生成数据调用方法对应的参数,前段传入的参数*/public List<MockItemParamters> inParameters;/*** @ 返回数据时的key*/private  String key;}

MockItemParamters(调用方法时传入的参数以及参数类型)

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MockItemParamters {/*** @ 名称对应Params参数*/private Object Params;/*** @ 名称对应Params参数类型*/Class<?> clazz;}

最终实现的工具类GenerateData

public class GenerateData{/*** TODO* @param: faker* @param: mockItem 生成数据是调用的方法,方法需要的参数及类型以及输出数据时的key* @param: number 生成假数据的条数* @param: clazz 需要输出的实体*/public static <T> List<T> generatList(Faker faker, List<MockItem> mockItem, int number, Class<T> clazz) throws Exception {List<T> listResult = new ArrayList<>();for(int i = 0; i < number; i++){listResult.add(i,generateEntity(faker,mockItem,clazz));}return listResult;}public static List<Map<String, Object>> generatListMap(Faker faker,List<MockItem> mockItem,int number){List<Map<String, Object>> listResult = new ArrayList<>();for(int i=0;i<number;i++){listResult.add(i,generateMap(faker,mockItem));}return listResult;}/*** TODO* @Description: 一次生成一条Map假数据* @return: listResultdata*/public static Map<String, Object> generateMap(Faker faker,List<MockItem> mockItem){Map<String,Object> listResultdata = new HashMap<>();try {for (MockItem m : mockItem) {listResultdata.put(m.getKey(),generateSingleData(faker,m));}}catch (Exception e){throw new RuntimeException("Data generation failed", e);}return listResultdata;}/*** TODO* @Description: 一次生成一条数据,核心在于利用BeanUtils.setProperty反射机制* @return: T*/public static <T> T generateEntity(Faker faker,List<MockItem> mockItem, Class<T> clazz){try {T result = clazz.newInstance();for (MockItem mock : mockItem) {Object value = generateSingleData(faker, mock);BeanUtils.setProperty(result, mock.getKey(), value);}return result;}catch (Exception e){throw new RuntimeException("Data generation failed", e);}}/*** TODO* @Description: 调用Faker方法一次生成一个数据* @return: (T)*/public static Object generateSingleData(Faker faker,MockItem mockItem) throws Exception{String[] methods = mockItem.getMethodNames().split("\\.");if(methods.length != 2) {throw new RuntimeException("methodNames is not invaild");}Object firstMethod = faker.getClass().getMethod(methods[0]).invoke(faker);//获取到faker第一个方法的调用句柄Class<?> firstMethodClass = firstMethod.getClass();if(mockItem.getInParameters() != null) {Class<?>[] clazz = typeConversion(mockItem.getInParameters());Object[] paramets = parameterConversion(mockItem.getInParameters());//getMethod的第二个参数parameterTypes是按声明顺序标识该方法形参类型。return firstMethodClass.getMethod(methods[1], clazz).invoke(firstMethod, paramets);}return firstMethodClass.getMethod(methods[1]).invoke(firstMethod);}/*** TODO* @Description: 根据调用者提供的数据类型进行相对应的转换(类型转换)主要用在getMethod的第二个参数parameterTypes需要声明方法形参类型* @param: mockItemParamters 参数类包含参数及参数类型* @return: Class<?>[]*/public static Class<?>[] typeConversion(List<MockItemParamters> mockItemParamters){Class<?>[] clazz = new Class<?>[mockItemParamters.size()];//遍历获取形参类型以及转换参数int i = 0;for(MockItemParamters m : mockItemParamters){if(int.class == m.getClazz() || Integer.class == m.getClazz()){clazz[i] = int.class;}else if(boolean.class == m.getClazz() || Double.class == m.getClazz()){clazz[i] = boolean.class;}else if(long.class == m.getClazz() || Long.class == m.getClazz()){clazz[i] = long.class;}else if(byte.class == m.getClazz() || Byte.class == m.getClazz()){clazz[i] = byte.class;}else if(float.class == m.getClazz() || Float.class == m.getClazz()){clazz[i] = float.class;}else if(double.class == m.getClazz() || Double.class == m.getClazz()){clazz[i] = double.class;}else if(short.class == m.getClazz() || Short.class == m.getClazz()){clazz[i] = short.class;}else{clazz[i] = String.class;}i++;}return clazz;}/*** TODO* @Description: 根据调用者提供的数据类型进行相对应的转换(参数类型转换)* @param: mockItemParamters参数类包含参数及参数类型* @return: Class<?>[]*/public static Object[] parameterConversion(List<MockItemParamters> mockItemParamters){Object[] paramets = new Object[mockItemParamters.size()];//遍历获取形参类型以及转换参数int i = 0;for(MockItemParamters m : mockItemParamters){if(int.class == m.getClazz() || Integer.class == m.getClazz()){//int a = ConvertUtils.convert(m.getParams(),int.class,true);paramets[i] = (Integer.parseInt(m.getParams().toString()));}else if(boolean.class == m.getClazz() || Double.class == m.getClazz()){paramets[i] = (Boolean.parseBoolean(m.getParams().toString()));}else if(long.class == m.getClazz() || Long.class == m.getClazz()){paramets[i] = (Long.parseLong(m.getParams().toString()));}else if(byte.class == m.getClazz() || Byte.class == m.getClazz()){paramets[i] = (Byte.parseByte(m.getParams().toString()));}else if(float.class == m.getClazz() || Float.class == m.getClazz()){paramets[i] = (Float.parseFloat(m.getParams().toString()));}else if(double.class == m.getClazz() || Double.class == m.getClazz()){paramets[i] = (Double.parseDouble(m.getParams().toString()));}else if(short.class == m.getClazz() || Short.class == m.getClazz()){paramets[i] = (Short.parseShort(m.getParams().toString()));}else{paramets[i] = (m.getParams().toString());}i++;}return paramets;}public static void main(String[] args) throws Exception {Faker faker = Faker.instance(Locale.CHINA);List<MockItem> mockItemList = new ArrayList<>();//参数List<MockItemParamters> mockItemParamters = new ArrayList<>();MockItemParamters MockItemParamters = new MockItemParamters();MockItemParamters.setParams(2);MockItemParamters.setClazz(int.class);MockItemParamters MockItemParamters1 = new MockItemParamters();MockItemParamters1.setParams(2);MockItemParamters1.setClazz(int.class);MockItemParamters MockItemParamters2 = new MockItemParamters();MockItemParamters2.setParams(99);MockItemParamters2.setClazz(int.class);mockItemParamters.add(MockItemParamters);mockItemParamters.add(MockItemParamters1);mockItemParamters.add(MockItemParamters2);MockItem mockItem = new MockItem();mockItem.setMethodNames("name.fullName");mockItem.setKey("name");MockItem mockItem1 = new MockItem();mockItem1.setMethodNames("number.randomDouble");mockItem1.setInParameters(mockItemParamters);mockItem1.setKey("value");mockItemList.add(mockItem);mockItemList.add(mockItem1);//输入的参数System.out.println("输入的参数~~~~~~~~~~~~~~~~~"+mockItemList);//根据实体类生成List<***> **=  generatList(faker,mockItemList,10,     ***.class);System.out.println("根据实体映射输出的list结果~~~~~~~~~~~~~~~~~"+**);//生成map类型List<Map<String,Object>>  listMap =  generatListMap(faker, mockItemList, 10);System.out.println("输出的listMap结果~~~~~~~~~~~~~~~~~"+listMap );}
}

输出结果

输入的参数~~~~~~~~~~~~~~~~~[MockItem(methodNames=name.fullName, inParameters=null, key=name), MockItem(methodNames=number.randomDouble, inParameters=[MockItemParamters(Params=2, clazz=int), MockItemParamters(Params=2, clazz=int), MockItemParamters(Params=99, clazz=int)], key=value)]
根据实体映射输出的10条结果~~~~~~**实体类名称~~~~~~~~~~~[**(name=苏梓晨, value=39.76), **(name=叶昊然, value=47.0), **(name=张笑愚, value=67.61), **(name=黎峻熙, value=77.59), **(name=覃彬, value=14.1), **(name=贺展鹏, value=8.53), **(name=覃致远, value=77.93), **(name=谢煜城, value=35.23), **(name=孙风华, value=29.26), **(name=赖志泽, value=15.06)]
输出的10条Map结果~~~~~~~~~~~~~~~~~[{name=崔天磊, value=78.89}, {name=邱思聪, value=44.28}, {name=陆伟宸, value=57.53}, {name=宋远航, value=19.53}, {name=曾炫明, value=82.85}, {name=周鹏飞, value=82.98}, {name=谭文博, value=78.05}, {name=陈瑾瑜, value=15.98}, {name=史明辉, value=56.29}, {name=尹正豪, value=13.07}]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

将Faker中的方法以及参数类型输出到数据库中

根据自己框架把 super.save修改为自己的插入数据的方法即可(insert语句)

    public void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Faker faker = Faker.instance( Locale.CHINA);Field[] fileds = faker.getClass().getDeclaredFields();for( Field f1:fileds ){UtilFakerPO utilFakerPO = new UtilFakerPO();utilFakerPO.setCreateTime(new Date());utilFakerPO.setEhName(f1.getName());utilFakerPO.setMthod(f1.getName());utilFakerPO.setParentId(0l);super.save(utilFakerPO);UtilFakerParameterinfoVo details = ConvertUtils.convertIgnoreNull(utilFakerPO, UtilFakerParameterinfoVo.class);if(!"fakeValuesService".equals(f1.getName())){String name = f1.getName();if("randomService".equals(f1.getName())){name = "random";}else if("dateAndTime".equals(f1.getName())){name = "date";}Object object = faker.getClass().getMethod(name).invoke(faker);Method[] methods = object.getClass().getDeclaredMethods();for (Method method:methods){String methodName = method.getName();UtilFakerPO utilFakerchild = new UtilFakerPO();utilFakerchild.setCreateTime(new Date());utilFakerchild.setEhName(methodName);utilFakerchild.setMthod(name+"."+methodName);utilFakerchild.setParentId(details.getId());super.save(utilFakerchild);UtilFakerParameterinfoVo detailschild = ConvertUtils.convertIgnoreNull(utilFakerchild, UtilFakerParameterinfoVo.class);Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> clas:parameterTypes){String parameterName = clas.getSimpleName();UtilFakerParameterinfoPO utilFakerParameterinfoPO = new UtilFakerParameterinfoPO();utilFakerParameterinfoPO.setCreateTime(new Date());utilFakerParameterinfoPO.setDataType(parameterName);utilFakerParameterinfoPO.setUtilFakerId(detailschild.getId());super.save(utilFakerParameterinfoPO);}}}}};

上面代码中类型转换与参数转换应该有更好的办法,我暂时没有查到,如果大神有更好的方法求指教,写下这篇文章纯属为了学习,记录。同时也希望能给他人提供帮助。

java生成假数据工具类-基于Faker1.0.2相关推荐

  1. Java开发中的工具类——基于JedisPool的Redis工具类

    目录 一.Maven依赖 二.Redis配置类 三.使用@Cacheable注解进行数据缓存 四.自定义Redis工具类及使用 4.1 序列化工具类 4.2 redis客户端工具类 4.3 redis ...

  2. 使用java多线程分批处理数据工具类

    最近由于业务需要,数据量比较大,需要使用多线程来分批处理,提高处理效率和能力,于是就写了一个通用的多线程处理工具,只需要实现自己的业务逻辑就可以正常使用,现在记录一下 主要是针对大数据量list,将l ...

  3. java生成圆_java工具类-java实现 生成圆头像

    1.创建RoundHeadImgUtils工具类 package com.mrd.utils; import javax.imageio.ImageIO; import java.awt.*; imp ...

  4. java生成假数据--javafaker

    1.前言 在工作中我们总是避免不了需要一些测试数据的支持,可是动辄成千上万条的数据编写起来让我们头痛不已,尤其是一些刁钻的场景还需要"假数据"不那么"假",因此 ...

  5. java 导出mdb文件_Java中Java生成mdb文件工具类

    package com.util; /**  * Java生成mdb文件[MS Access文件]  * 1. 在ClassPath下存一个空的blank.mdb. (也就是在你的项目中包含一个空白的 ...

  6. java 生成水印图片工具类, MultipartFile接收上传的图片,处理成加水印之后的MultipartFile

    /*** Created by Administrator on 2018/4/26.* JAVA图片处理工具*/ public class ImageUtil {public enum positi ...

  7. java 生成UUID字符串工具类 UUIDUtil

    package com.xj.hhjk.common.util.security; import java.util.UUID; import java.util.regex.Matcher; imp ...

  8. java生成验证码工具类_Java生成图形验证码工具类

    生成验证码效果 validatecode.java 验证码生成类 package cn.dsna.util.images; import java.awt.color; import java.awt ...

  9. java开发excel导入导出工具类基于EasyExcel

    一.工具类 import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.style.column.LongestMatchCo ...

  10. java file ip_java常用工具类 IP、File文件工具类

    本文实例为大家分享了java常用工具类的具体实现代码,供大家参考,具体内容如下 IP工具类 package com.jarvis.base.util; import java.io.IOExcepti ...

最新文章

  1. Keil精确测量代码运行时间
  2. kafka 、 zookeeper 集群(一)
  3. python string模块template_Template Strings
  4. java super和this总结
  5. 从物联网发展历程看区块链挑战
  6. Qt元对象和属性机制
  7. python并行编程手册 pdf_Python并行编程手册
  8. 软件开发人员的简历项目经验
  9. 北京地铁,4号线换乘13号线,用时最短换乘线路
  10. 学会使用distribute-list过滤路由更新
  11. 【搬运】1 简谱和基本知识
  12. win32分割窗口的一个简易做法,非常好的编程思维(一)
  13. CaEGCN: Cross-Attention Fusion based Enhanced Graph Convolutional Network for Clustering 2021
  14. 计算机专业评测绘工程师,如何成为测绘工程师
  15. Swagger的 @Api
  16. PC端各浏览器布局兼容问题【Chrome、Firefox、IE】——长期更新
  17. HanLP自然语言处理包介绍
  18. JS 自定义实现数字滚动处理
  19. 支付宝当面付扫码支付接口开发
  20. 人脉变现小程序裂变定制开发

热门文章

  1. html树状图怎么搜索节点,echarts2.* tree树形图节点点击事件和节点点击图标更改...
  2. 计算机没声音怎么解决,【电脑没有声音】电脑没有声音怎么办_电脑没有声音是什么原因-太平洋IT百科...
  3. bzoj 4238: 电压 dfs树
  4. 弹簧卸扣的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  5. 一WAN多拨(一号多拨)实验
  6. python语句用什么隔开_在python中使用字典时用什么隔开
  7. Android基础课程:第三方视频播放器(播放网络资源)
  8. C语言——类型限定词
  9. Java 运算符 输入 分支语句
  10. 关于眼镜的一些知识收集