1. 概述
本教程将探讨如何为不同场景生成模拟数据。我们将学习如何使用 Datafaker 并通过多个示例深入理解其用法。
2. 发展历程
Datafaker 是 Javafaker 的现代分支版本。 它迁移至 Java 8 并进行了多项改进,显著提升了库的性能。但当前 API 基本保持不变,因此从 Javafaker 迁移到 Datafaker 不会遇到兼容性问题。本文提供的所有示例均适用于 Datafaker 1.6.0 版本。
当前 Datafaker API 与 Javafaker 兼容。因此本文将重点介绍差异点和改进特性。
首先添加 Maven 依赖:
<dependency>
<groupId>net.datafaker</groupId>
<artifactId>datafaker</artifactId>
<version>1.6.0</version>
</dependency>
3. 数据提供者
Datafaker 的核心组件是数据提供者。这是一组特殊类,使数据生成更便捷。这些类由包含真实数据的yml 文件支持。Faker 方法和表达式直接或间接使用这些文件生成数据。后续章节将深入解析这些方法和指令的工作原理。
4. 新增数据生成模式
Datafaker 和 Javafaker 都支持基于模式生成数据。Datafaker 新增了 templatify, exemplify, options, date, csv, json 等指令。
4.1. Templatify 模板化
templatify 指令接收多个参数:
- 基础字符串
- 待替换字符
- 随机替换选项列表
public class Templatify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("表达式: " + getExpression());
System.out.println("带占位符表达式: " + getExpressionWithPlaceholder());
}
static String getExpression() {
return faker.expression("#{templatify 'test','t','j','r'}");
}
static String getExpressionWithPlaceholder() {
return faker.expression("#{templatify '#ight', '#', 'f', 'l', 'm', 'n'}");
}
}
⚠️ 虽然可以直接使用基础字符串,但可能产生意外结果(会替换所有匹配字符)。建议使用占位符(仅在特定位置出现的字符):
表达式: resj
带占位符表达式: night
✅ 当存在多个可替换位置时,每次都会随机选择。虽然支持字符串替换,但文档未明确说明,建议谨慎使用。
4.2. Examplify 示例化
该指令根据提供的示例生成随机值:
- 小写/大写字母 → 随机同类字母
- 数字 → 随机数字
- 特殊字符保持不变(便于创建格式化字符串)
public class Examplify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("字符串表达式: " + getExpression());
System.out.println("数字表达式: " + getNumberExpression());
}
static String getExpression() {
return faker.expression("#{examplify 'Cat in the Hat'}");
}
static String getNumberExpression() {
return faker.expression("#{examplify '123-123-123'}");
}
}
输出示例:
字符串表达式: Lvo lw ero Qkd
数字表达式: 707-657-434
4.3. Regexify 正则化
创建格式化字符串的更灵活方式:
public class Regexify {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("表达式: " + getExpression());
System.out.println("方法调用: " + getMethodExpression());
}
static String getExpression() {
return faker.expression("#{regexify '(hello|bye|hey)'}");
}
static String getMethodExpression() {
return faker.regexify("[A-D]{4,10}");
}
}
输出示例:
表达式: bye
方法调用: DCCC
4.4. Options 选项
从指定列表中随机选择选项(虽然可用 regexify 实现,但独立指令更便捷):
public class Option {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("表达式1: " + getFirstExpression());
System.out.println("表达式2: " + getSecondExpression());
System.out.println("正则对比: " + getThirdExpression());
}
static String getFirstExpression() {
return faker.expression("#{options.option 'Hi','Hello','Hey'}");
}
static String getSecondExpression() {
return faker.expression("#{options.option '1','2','3','4','*'}");
}
static String getThirdExpression() {
return faker.expression("#{regexify '(Hi|Hello|Hey)'}");
}
}
输出示例:
表达式1: Hey
表达式2: 4
正则对比: Hello
❌ 当选项过多时,建议创建自定义提供者。
4.5. CSV 生成
生成 CSV 格式数据。⚠️ 注意:该指令由两个重载方法处理,容易混淆:
public class Csv {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("基础用法:\n" + getFirstExpression());
System.out.println("高级用法:\n" + getSecondExpression());
}
static String getFirstExpression() {
String expr = "#{csv '4','name_column','#{Name.first_name}','last_name_column','#{Name.last_name}'}";
return faker.expression(expr);
}
static String getSecondExpression() {
String expr = "#{csv ',','\"','true','4','name_column','#{Name.first_name}','last_name_column','#{Name.last_name}'}";
return faker.expression(expr);
}
}
输出示例:
基础用法:
"name_column","last_name_column"
"Riley","Spinka"
"Lindsay","O'Conner"
"Sid","Rogahn"
"Prince","Wiegand"
高级用法:
"name_column","last_name_column"
"Jen","Schinner"
"Valeria","Walter"
"Mikki","Effertz"
"Deon","Bergnaum"
✅ 这是生成外部程序所需模拟数据的绝佳方式。
4.6. JSON 生成
通过表达式生成 JSON 数据:
public class Json {
private static final Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getExpression());
}
static String getExpression() {
return faker.expression(
"#{json 'person'," + "'#{json ''first_name'',''#{Name.first_name}'',''last_name'',''#{Name.last_name}''}'," +
"'address'," + "'#{json ''country'',''#{Address.country}'',''city'',''#{Address.city}''}'}");
}
}
输出示例:
{"person": {"first_name": "Dorian", "last_name": "Simonis"}, "address": {"country": "Cameroon", "city": "South Ernestine"}}
4.7. 方法调用
所有表达式本质上都是方法调用,方法名和参数以字符串形式传递。因此前述指令都有对应方法:
public class MethodInvocation {
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("方法调用: " + getNameFromMethod());
System.out.println("表达式调用: " + getNameFromExpression());
}
static String getNameFromMethod() {
return faker.name().firstName();
}
static String getNameFromExpression() {
return faker.expression("#{Name.first_Name}");
}
}
✅ 表达式可直接调用 Faker 对象的任意数据生成方法(方法名不区分大小写,但建议参考文档确认)。
还支持带参数的方法调用:
public class MethodInvocationWithParams {
public static int MIN = 1;
public static int MAX = 10;
public static String UNIT = "SECONDS";
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println("方法调用: " + getDurationFromMethod());
System.out.println("表达式调用: " + getDurationFromExpression());
}
static Duration getDurationFromMethod() {
return faker.date().duration(MIN, MAX, UNIT);
}
static String getDurationFromExpression() {
return faker.expression("#{date.duration '1', '10', 'SECONDS'}");
}
}
❌ 表达式返回值固定为 String 类型,限制了后续操作:
方法调用: PT6S
表达式调用: PT4S
5. 集合生成
集合功能可生成包含模拟数据的列表,元素类型可不同。集合类型由所有元素类的最具体父类决定。生成《星球大战》和《星际迷航》角色列表:
public class Collection {
public static int MIN = 1;
public static int MAX = 100;
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getFictionalCharacters());
}
static List<String> getFictionalCharacters() {
return faker.collection(
() -> faker.starWars().character(),
() -> faker.starTrek().character())
.len(MIN, MAX)
.generate();
}
}
输出示例:
[Luke Skywalker, Wesley Crusher, Jean-Luc Picard, Greedo, Hikaru Sulu, William T. Riker]
✅ 当所有提供者返回 String 时,集合类型为 String。混合类型示例:
public class MixedCollection {
public static int MIN = 1;
public static int MAX = 20;
private static Faker faker = new Faker();
public static void main(String[] args) {
System.out.println(getMixedCollection());
}
static List<? extends Serializable> getMixedCollection() {
return faker.collection(
() -> faker.date().birthday(),
() -> faker.name().fullName())
.len(MIN, MAX)
.generate();
}
}
✅ String 和 Timestamp 的最具体父类是 Serializable:
[1964-11-09 15:16:43.0, Devora Stamm DVM, 1980-01-11 15:18:00.0, 1989-04-28 05:13:54.0,
2004-09-06 17:11:49.0, Irving Turcotte, Sherita Durgan I, 2004-03-08 00:45:57.0, 1979-08-25 22:48:50.0,
Manda Hane, Latanya Hegmann, 1991-05-29 12:07:23.0, 1989-06-26 12:40:44.0, Kevin Quigley]
6. 总结
Datafaker 是 Javafaker 的改进版本。本文介绍了 Datafaker 1.6.0 的新数据生成方式。要深入了解该库,建议参考官方文档和GitHub 仓库。
本文代码示例可在 GitHub 获取。