# 造数小工具 **Repository Path**: liu-jie-gistone/counting-gadget ## Basic Information - **Project Name**: 造数小工具 - **Description**: 造数据小工具,用于测试数据的自动化生成。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 10 - **Forks**: 7 - **Created**: 2022-08-25 - **Last Updated**: 2025-01-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 自定义构建测试数据工具 ### 主要功能 对mysql数据库批量构建模拟业务流程的测试数据,可用于系统压力测试、POC演示、BI报表展示、数据分析指标加工逻辑测试。 可自定义库表结构,自定义关联关系,支持复杂的数据结构生成。通过符合特定规则的JSON配置文件,转换成对数据库表的DDL操作和DML操作。 ### 目录结构 ``` . ├── README.md ├── config │   ├── custom-build-data.yml │   ├── dataconf │   │   ├── example │   │   │   ├── insurance.json │ │ │ ├── insurance_ddl.json │   │   │   └── insurance_ddl.sql │   │   └── increment.id │   └── logback.xml ├── lib ├── logs │   └── backup └── sbin └── start.sh ``` - README.md 说明文档 - config 配置文件目录 - custom-build-data.yml 工程配置文件 - dataconf 数据配置目录 - example 数据配置示例目录(包含一个保险业务示例) - increment.id 全局自增id文件存储 - logback.xml 日志配置文件 - lib 依赖包 - logs 日志目录 - sbin 执行脚本 ### 快速开始 #### 配置文件示例 ``` # 多线程配置 threadConfig: # 线程数 threadBuilderNumber: 5 # 每次批量大小 batchSize: 10 # 单线程调试 singleThreadDebug: false # 数据库配置 dataSourceConfig: dataSourceInfos: # 数据源A - dbKey: test driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://127.0.0.1:3308/ops?useSSL=false&characterEncoding=utf8&rewriteBatchedStatements=true username: root password: root # 是否开启自动删表建表DDL autoDDl: true # 序列化生成示例文件配置,从mysql数据库读取库表结构和数据序列化生成示例JSON exampleConfig: # 示例文件输出文件路径 generateExampleFilePath: /Users/hsy/nny/custom-build-data/target/custom-build-data-1.0.0/config/dataconf/example/ # 是否生成DDl示例文件 generateDDl: false # 是否生成DMl示例文件 generateDMl: false # 数据源列表 dataSourceInfos: - dbKey: test driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://127.0.0.1:3308/ops?useSSL=false&characterEncoding=utf8&rewriteBatchedStatements=true username: root password: root # 设置构建多少组数据 buildNumber: 1 # DML配置文件路径 dataJsonFilePath: /Users/hsy/nny/custom-build-data/target/custom-build-data-1.0.0/config/dataconf/example/insurance.json # DDL配置文件路径 dataDDLJsonFilePath: /Users/hsy/nny/custom-build-data/target/custom-build-data-1.0.0/config/dataconf/example/insurance_ddl.json # 自动生成的sql语句输出路径 sqlFileOutputFilePath: /Users/hsy/nny/custom-build-data/target/custom-build-data-1.0.0/ # 全局自增Id保存文件地址 globalAutoIncrementFilePath: /Users/hsy/nny/custom-build-data/target/custom-build-data-1.0.0/config/dataconf/increment.id ``` - 修改数据源配置中的mysql数据库为自己的测试库 - 修改DML配置文件路径为:部署目录/custom-build-data-1.0.0/config/dataconf/insurance.json(路径为绝对路径) - 修改DDL配置文件路径为:部署目录/custom-build-data-1.0.0/config/dataconf/insurance_ddl.json(路径为绝对路径) - 修改sql文件输出路径(路径为绝对路径) - 修改全局自增Id保存文件地址(路径为绝对路径) - 进入部署目录/custom-build-data-1.0.0目录,执行: sh sbin/start.sh config/custom-build-data.yml - 查看mysql数据库中,测试数据已经生成 - 查看sql文件输出路径,里面有生成的sql语句,可单独在其他mysql数据库直接执行同样也可生成测试数据 ### 配置文件详细说明 多线程配置 threadConfig ``` threadBuilderNumber: 构建数据线程数配置 batchSize: 每次批量执行的组数 singleThreadDebug: 是否开启单线程调试 ``` 数据库配置 dataSourceConfig ``` dataSourceInfos: 数据源列表(支持配置多个数据源) dbKey: 数据源标识,DML和DDL配置文件中会使用 driverClassName: 驱动 jdbcUrl: 数据库连接地址(加上rewriteBatchedStatements=true参数开启批量写,默认是关闭的) username: root password: root autoDDl: 是否开启自动删表建表DDL ``` 序列化生成示例文件配置 exampleConfig ``` 从mysql数据库读取所有库表结构序列化生成示例JSON generateExampleFilePath: 示例文件输出文件路径(绝对路径) generateDDl: 是否生成DDl示例文件 generateDMl: 是否生成DMl示例文件 dataSourceInfos: 数据源列表(支持配置多个数据源,配置与dataSourceConfig中的dataSourceInfos一致) ``` 构建多少组数据 buildNumber ``` buildNumber: 构建多少组数据,一个完整的业务流程为一组数据 ``` DML配置文件路径 dataJsonFilePath ``` dataJsonFilePath: 路径为绝对路径,DML配置,可配置INSERT、UPDATE语句,多条SQL语句为一组数据 ``` DML配置文件路径 dataDDLJsonFilePath ``` dataDDLJsonFilePath: 路径为绝对路径,DDL配置,自定义配置表结构,增加、删减字段便捷,只需要修改JSON文件即可 ``` 自动生成的sql语句输出路径 sqlFileOutputFilePath ``` sqlFileOutputFilePath: 路径为绝对路径,将DML配置文件中的INSERT、UPDATE业务逻辑生成SQL语句输出到文件中,可单独在其他mysql数据库直接执行同样也可生成测试数据,测试数据迁移便捷 ``` 全局自增Id保存文件地址 globalAutoIncrementFilePath ``` globalAutoIncrementFilePath:路径为绝对路径,保存全局的自增Id,每次生成数据时会加载文件中的Id值,数据生成完成之后,会将当前的Id值回写到文件中。 ``` #### DDL配置说明 - 配置表名称、表字段、表索引、表主键,进行DDL的生成。 - 如果想要对已存在的数据库表进行测试数据生成,可设置dataSourceConfig.autoDDl为false。将表中NOT NULL的字段补充到DML配置中,可直接生成数据。 基础结构 ``` columns:字段定义列表 dbKey:数据源Key,对应配置文件中的dbKey indexInfos:索引定义 primary:主键定义 tabelName:表名称 no:表编号 { "columns": [], "dbKey": "test", "indexInfos": [], "no": 1, "primary": [], "tableName": "insurance_customer_info" }, ``` columns 字段定义列表 ``` columnName:字段名称 columnType:字段类型 comment:字段注释 dataType:字段值类型(枚举值) isNullStr:字段是否允许为空(NOT NULL | NULL) { "columnName": "cust_id", "columnType": "int(11)", "comment": "客户id", "dataType": "INTEGER", "isNullStr": "NOT NULL" }, dataType可选枚举值: STRING("STRING", "VARCHAR"), INTEGER("INTEGER", "INT"), Boolean("Boolean", "BOOLEAN"), LONG("LONG", "INTEGER"), DATE("DATE", "DATETIME"), DOUBLE("DOUBLE", "DECIMAL"), Currency("Currency", "VARCHAR"), DICTIONARY("DICTIONARY", "VARCHAR"), TIMESTAMP("TIMESTAMP", "TIMESTAMP"), Maps("Maps", "VARCHAR"), Lists("Lists", "VARCHAR"), ListItem("ListItem", "VARCHAR"); ``` indexInfos 索引定义 ``` columnName:列名称 indexName:索引名称 [ { "columnName": "staff_id", "indexName": "staff_id" } ] ``` primary 主键定义 ``` 数组,支持联合主键 [ "cust_id" ] ``` #### DML配置说明 - 基于现有表配置INSERT、UPDATE语句,支持生成1对多数据。 基础结构 ``` scenarios:场景集合(数组,可配置多个场景,生成数据时会随机选择一个场景) desc:场景描述 tableInfos:表数据生成定义 { "scenarios": [ { "desc": "场景描述", "tableInfos": [ ] } ] } ``` tableInfos 表数据生成定义 ``` desc:对表执行的INSERT或UPDATE操作描述 columns:SQL语句字段定义 wheres:SQL语句where条件的字段定义(UPDATE时使用) relations:关联表数据生成定义 dbKey:数据源Key,对应配置文件中 conditionExpression:表数据是否进行生成的条件判断表达式,true则执行生成逻辑,否则跳过当前表操作的数据生成 no:表编号 operateMode:操作类型(INSERT|UPDATE) tableName:执行SQL语句的表名称 no+tabelName 表编号+表名称为DML数据中的唯一标识,因为某个表在一个业务流程中,可能会有INSERT多次或者是UPDATE多次操作。 { "desc": "INSERTxxx记录", "columns": [], "wheres": [], "relations": [], "dbKey": "test", "no": 2, "conditionExpression":"$1.insurance_claims.claims_approve_result} == "approve"" "operateMode": "INSERT", "tableName": "insurance_xxx_info" } ``` relations 关联表数据生成定义 ``` desc:关联表数据操作描述 relationType:关联类型(ONE_TO_MANY|ONE_TO_NNE) relationRowNumExpression:关联表达式,表达式的结果作为关联数据生成的条数(用于1对N关联,需要生成多条数据时使用)。 relationTableRowNum:指定关联表数据生成条数。 relationTable:关联表数据生成详细定义 `注意`:relationRowNumExpression和relationTableRowNum二选一,不能同时使用 { "desc": "INSERT保险单记录", "relationType": "ONE_TO_MANY", "relationRowNumExpression": "${1.insurance_customer_info.policy_number}", "relationTableRowNum":1, "relationTable": {} } ``` relationTable 关联表数据生成详细定义 ``` 结构与tableInfos的表数据生成定义基本一致。tableInStateDefinition特殊介绍。 tableInStateDefinition:用与1对N数据生成时中间状态数据使用。 tableFixedValues:已知当前表必须生成3行数据,p_type为列名称,每一行p_type的值都不一致,需要提前定义好。可使用该属性进行固定值的定义。支持多个数据列。 { "tableInStateDefinition": { "tableFixedValues": { "p_type": [ "P001", "P002", "P003" ] } }, "columns": [], "wheres": [], "dbKey": "test", "no": 2, "operateMode": "INSERT", "tableName": "insurance_policy" } ``` columns SQL语句字段定义 ``` columnName:字段名称 comment:字段注释 dataType:字段值数据类型 valueRule:字段值计算规则 { "columnName": "project_name", "comment": "保单项目名称", "dataType": "STRING", "valueRule": {} } ``` valueRule 字段值计算规则 ``` 自定义表达式介绍: ${3.insurance_claims.claims_approve_result} ${表编号.表名称.表字段} 1. 表达式中使用的“表编号.表名称.表字段”都必须是已经计算完成的。 2. 计算是按照表编号顺序计算,一般配置时是从上至下,只能引用之前的INSERT或UPDATE中的字段,不能引用之后的。可以引用当前table中的字段,但必须也是计算完成的字段。 3. 比如示例中:${2.insurance_policy}表操作在配置中,available_amount字段的表达式中可以引用insured_amount,因为计算available_amount时,insured_amount字段已经计算完成了,值已经有了。 4. 比如示例中:${2.insurance_policy}表操作在配置中,cust_id字段的表达式中可以引用${1.insurance_customer_info.cust_id},但不能引用${3.insurance_claims}中的任何一个字段。 ------- type:规则类型,类型不同的会执行不同的规则计算 boolExpression:布尔表达式,为true使用计算逻辑,否则使用defaultValue的值,不配置时默认为true defaultValue:默认值,不配置默认为null { "type":"RANDOM_MONEY", "boolExpression":"${3.insurance_claims.claims_approve_result} == "approve"", "defaultValue":0, } 规则类型说明 默认规则:NORMAL 随机选择器:SELECTOR 随机字符串:RANDOM_STRING 随机金额:RANDOM_MONEY 随机数字:RANDOM_NUMBER 随机日期:RANDOM_DATE 随机手机号:RANDOM_MOBILE 表内自增值:CONTINUOUS_VALUE 身份证:ID_CARD 引用字段:REFERENCE 随机名字:RANDOM_NAME 省份:PROVINCE 城市:CITY 区县:DISTRICT 生日:BIRTH 固定值规则:FIXED_VALUE 动态值规则:DYNAMIC_VALUE 表达式计算:EXPRESSION 全局自增值:GLOBAL_AUTO_INCREMENT > 默认规则:NORMAL,直接使用默认值,不会经过boolExpression判断 "valueRule": { "type": "NORMAL" "defaultValue":1 } > 随机选择器:SELECTOR,如果boolExpression成立,则会随机在valueArray中选择一个值返回作为字段值,不成立直接返回defaultValue的值,也可以不使用boolExpression,直接随机返回一个valueArray的值 "valueRule": { "type": "SELECTOR" "valueArray":[2,3,4] } > 随机字符串:RANDOM_STRING,boolExpression同上,创建一个前缀为B字符串的19位随机字符串 "valueRule": { "type": "RANDOM_STRING" "prefix":"B" } > 随机金额:RANDOM_MONEY,boolExpression同上,compareExpression比较表达式,(有一个参数必须是当前计算字段,被比较的字段必须已经计算完成)两个字段进行比较计算,把当前生成的随机金额值不断的放入表达式中进行计算,当表达式成立时返回生成结果,不成立则不断循环生成结果,直到表达式成立,${2.表2.金额2}为当前表当前字段。不使用compareExpression时,随机生成一个金额 "valueRule": { "type": "RANDOM_MONEY" "compareExpression":"${2.表2.金额2} < ${1.表1.金额1}" } > 随机数字:RANDOM_NUMBER,boolExpression同上,随机生成一个32位的数字字符串 "valueRule": { "type": "RANDOM_NUMBER" } > 随机日期:RANDOM_DATE,boolExpression同上,compareExpression比较表达式,(有一个参数必须是当前计算字段,被比较的字段必须已经计算完成)两个字段进行比较计算,把当前生成的随机日期值不断的放入表达式中进行计算,当表达式成立时返回生成结果,不成立则不断循环生成结果,直到表达式成立,${2.表2.柔情哦2}为当前表当前字段。不使用compareExpression时,随机生成一个日期 "valueRule": { "type": "RANDOM_MONEY" "compareExpression":"${2.表2.日期2} < ${1.表1.日期1}" } > 随机手机号:RANDOM_MOBILE,boolExpression同上,随机生成一个电话号码 "valueRule": { "type": "RANDOM_MOBILE" } > 表内自增值:CONTINUOUS_VALUE,boolExpression同上,生成从1开始的表内自增值,表数据生成完成之后,自增值又从1开始(一般用于1对多数据,第一条数据字段值为1,第二条数据字段值为2) "valueRule": { "type": "CONTINUOUS_VALUE" } > 身份证:ID_CARD",boolExpression同上,随机生成一个身份证号 "valueRule": { "type": "ID_CARD" } > 引用字段:REFERENCE,boolExpression同上,使用引用表达式refColumnExpression,直接引用一个当前表或者之前表已经计算好的字段值。format表示是否进行格式转换,默认为false,如果你的columnType为DOUBLE将会返回一个Double的值,fewDecimalPlaces保留几位小数,默认0。 "valueRule": { "type": "REFERENCE" "refColumnExpression":"${表编号.表名称.表字段}", "format":true, "fewDecimalPlaces":2 } > 随机名字:RANDOM_NAME,boolExpression同上,随机生成一个名字 "valueRule": { "type": "RANDOM_NAME" "refColumnExpression":"${表编号.表名称.表字段}" } > 省份:PROVINCE,boolExpression同上,使用引用表达式refColumnExpression传入身份证字段,生成省份编号字符串 "valueRule": { "type": "PROVINCE" "refColumnExpression":"${表编号.表名称.身份证字段}" } > 城市:CITY,boolExpression同上,使用引用表达式refColumnExpression传入身份证字段,生成城市编号字符串 "valueRule": { "type": "CITY" "refColumnExpression":"${表编号.表名称.身份证字段}" } > 区县:DISTRICT,boolExpression同上,使用引用表达式refColumnExpression传入身份证字段,生成区县编号字符串 "valueRule": { "type": "DISTRICT" "refColumnExpression":"${表编号.表名称.身份证字段}" } > 生日:BIRTH,boolExpression同上,使用引用表达式refColumnExpression传入身份证字段,生成生日字符串 "valueRule": { "type": "BIRTH" "refColumnExpression":"${表编号.表名称.身份证字段}" } > 固定值规则:FIXED_VALUE,boolExpression同上,用于1对多数据,根据表数据当前对应的行数作为下标到取值,当前1对多数据的行号超过tableFixedValues的最大下标值时全部使用fixedPlaceholder属性作为替代值 "valueRule": { "type": "FIXED_VALUE" } > 动态值规则:DYNAMIC_VALUE,boolExpression同上,用于1对多数据,根据表数据当前对应的行数作为下标到取值,当前1对多数据的行号超过tableDynamicValues的最大下标值时全部使用dynamicPlaceholder属性作为替代值 "valueRule": { "type": "DYNAMIC_VALUE" } > 表达式计算:EXPRESSION,boolExpression同上,支持复杂的表达式计算,支持自定义函数调用,使用Aviator进行表达式计算 "valueRule": { "type": "EXPRESSION" "expression":"(${表编号.表名称.表字段} + ${表编号.表名称.表字段}) * 30" } > 全局自增值:GLOBAL_AUTO_INCREMENT,boolExpression同上,全局的自增值,每次数据生成完成之后,会把值写入到文件中进行保存,下次生成数据时再次进行读取。 "valueRule": { "type": "GLOBAL_AUTO_INCREMENT" } ```