Skip to content

linmeibao/custom-build-data

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

自定义构建测试数据工具

主要功能

对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:https://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:https://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"
}