sqlfather笔记

这里简单记录写学习鱼皮sqlfather项目的笔记,以供以后学习。

运行

将前后端项目clone到本地后,修改对应配置文件运行项目。

后端

1.配置好mysql后运行这个sql文件建立对应的表。

2.修改数据库密码

3.修改完后运行启动类即可

  1. 启动结果

5.查看API接口浏览器输入http://localhost:8102/api/doc.html![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2280a2c0d9e6440c9a62b49c53ef2f2b.png)

前端

前段代码不需要做修改,将代码下载到本地后,在终端窗口输入命令

shell 复制代码
// 安装依赖
yarn install // 如果提示没有yarn,先npm下载一下
// 运行程序
npm run dev 

运行效果

代码

代码结构

代码结构如上图所示,其中core文件夹主要用于成sql数据。

  • builder:生成sql语句,JSON数据,java代码,前段代码
  • generator:生成模拟数据(固定值,随机值,自增值,根据正则表达式生成等)
  • model:实体
  • schema:构造表时的统一规范
  • utils: 随机数生成 工具,可以生成姓名、邮箱、城市、IP、URL、日期、时间戳、手机号等数据。

代码解析

生成表

这里以生成student表为例

  1. 前段发送请求 http://localhost:8102/api/sql/generate/schema,映射到后端/sql/generate/schema方法

    这里为了方便生成,将前段定义的数据统一转化为了TableShema类型,包括库名、表名、字段名等信息。
java 复制代码
package com.yupi.sqlfather.core.schema;

import java.util.List;
import lombok.Data;

/**
 * 表概要
 *
 * @author https://github.com/liyupi
 */
@Data
public class TableSchema {

    /**
     * 库名
     */
    private String dbName;

    /**
     * 表名
     */
    private String tableName;

    /**
     * 表注释
     */
    private String tableComment;

    /**
     * 模拟数据条数
     */
    private Integer mockNum;

    /**
     * 列信息列表
     */
    private List<Field> fieldList;

    /**
     * 列信息
     */
    @Data
    public static class Field {
        /**
         * 字段名
         */
        private String fieldName;

        /**
         * 字段类型
         */
        private String fieldType;

        /**
         * 默认值
         */
        private String defaultValue;

        /**
         * 是否非空
         */
        private boolean notNull;

        /**
         * 注释(字段中文名)
         */
        private String comment;

        /**
         * 是否为主键
         */
        private boolean primaryKey;

        /**
         * 是否自增
         */
        private boolean autoIncrement;

        /**
         * 模拟类型(随机、图片、规则、词库)
         */
        private String mockType;

        /**
         * 模拟参数
         */
        private String mockParams;

        /**
         * 附加条件
         */
        private String onUpdate;
    }

}
  1. 然后会进入GeneratorFacade类中的generateAll()方法来生成所需数据
    这里首先会进行信息校验,然后会生成模拟数据、插入的sql数据、json数据等信息。

    2.1 DataBuilder.generateDate()方法生成模拟数据
    该方法用于生成模拟数据,返回一个List<Map<String, Object>>集合

    这里会对字段列表(fieldList)进行遍历,根据对应的模拟数据类型生成对应数据。
  • 先会先获取对应字段的模拟类型,这里以姓名字段为例,模拟数据类型为随机生成。通过调用DataGeneratorFactory.getGenerator()方法获取对应的枚举类型,这里采用了饿汉模式,首先构建多种DataGenerator对象,再根据请求的枚举类型返回对应的结果。
java 复制代码
package com.yupi.sqlfather.core.generator;

import com.yupi.sqlfather.core.model.enums.MockTypeEnum;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 数据生成器工厂
 * 工厂 + 单例模式,降低开销
 *
 * @author https://github.com/liyupi
 */
public class DataGeneratorFactory {

    /**
     * 模拟类型 => 生成器映射
     */
    private static final Map<MockTypeEnum, DataGenerator> mockTypeDataGeneratorMap = new HashMap<MockTypeEnum, DataGenerator>() {{
        put(MockTypeEnum.NONE, new DefaultDataGenerator());
        put(MockTypeEnum.FIXED, new FixedDataGenerator());
        put(MockTypeEnum.RANDOM, new RandomDataGenerator());
        put(MockTypeEnum.RULE, new RuleDataGenerator());
        put(MockTypeEnum.DICT, new DictDataGenerator());
        put(MockTypeEnum.INCREASE, new IncreaseDataGenerator());
    }};

    private DataGeneratorFactory() {
    }

    /**
     * 获取实例
     *
     * @param mockTypeEnum
     * @return
     */
    public static DataGenerator getGenerator(MockTypeEnum mockTypeEnum) {
        mockTypeEnum = Optional.ofNullable(mockTypeEnum).orElse(MockTypeEnum.NONE);
        return mockTypeDataGeneratorMap.get(mockTypeEnum);
    }
}
  • 然后会调用dataGenerator.doGenerate()方法来生成模拟数据

    这里的FakerUtils为生成模拟数据的工具类
java 复制代码
package com.yupi.sqlfather.core.utils;

import com.yupi.sqlfather.core.model.enums.MockParamsRandomTypeEnum;
import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import net.datafaker.Faker;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;

/**
 * 随机数生成工具
 *
 * @author https://github.com/liyupi
 */
public class FakerUtils {

    private final static Faker ZH_FAKER = new Faker(new Locale("zh-CN"));

    private final static Faker EN_FAKER = new Faker();

    private final static DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 获取随机值
     *
     * @param randomTypeEnum
     * @return
     */
    public static String getRandomValue(MockParamsRandomTypeEnum randomTypeEnum) {
        String defaultValue = RandomStringUtils.randomAlphanumeric(2, 6);
        if (randomTypeEnum == null) {
            return defaultValue;
        }
        switch (randomTypeEnum) {
            case NAME:
                return ZH_FAKER.name().name();
            case CITY:
                return ZH_FAKER.address().city();
            case EMAIL:
                return EN_FAKER.internet().emailAddress();
            case URL:
                return EN_FAKER.internet().url();
            case IP:
                return ZH_FAKER.internet().ipV4Address();
            case INTEGER:
                return String.valueOf(ZH_FAKER.number().randomNumber());
            case DECIMAL:
                return String.valueOf(RandomUtils.nextFloat(0, 100000));
            case UNIVERSITY:
                return ZH_FAKER.university().name();
            case DATE:
                return EN_FAKER.date()
                        .between(Timestamp.valueOf("2022-01-01 00:00:00"), Timestamp.valueOf("2023-01-01 00:00:00"))
                        .toLocalDateTime().format(DATE_TIME_FORMATTER);
            case TIMESTAMP:
                return String.valueOf(EN_FAKER.date()
                        .between(Timestamp.valueOf("2022-01-01 00:00:00"), Timestamp.valueOf("2023-01-01 00:00:00"))
                        .getTime());
            case PHONE:
                return ZH_FAKER.phoneNumber().cellPhone();
            default:
                return defaultValue;
        }
    }

    public static void main(String[] args) {
        getRandomValue(null);
    }

}

最终generateData方法得到的数据为

2.2 生成插入SQL

  • 通过buildInsertSql()生成对应sql语句

    生成结果

    2.3 生成JSON数据

    2.4 生成java实体对象代码

    生成结果:
java 复制代码
import lombok.Data;

/**
 * Student
 */
@Data
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    private Long id;

    /**
     * 用户名
     */
    private String name;

    /**
     * 性别
     */
    private Integer sex;

    /**
     * 用户名
     */
    private Integer age;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 是否删除(0-未删, 1-已删)
     */
    private Integer isDeleted;

}

java_entity.ftl模板

这里用到了FreeMarker template,详细信息可以看鱼皮大佬的介绍,https://www.codefather.cn/post/1732359794150469634

2.5 生成java对象代码

生成结果:

Student student = new Student();

student.setName("陈文轩");

student.setSex(0);

student.setAge(5);

2.6 生成ts代码

xml 复制代码
/**
 * Student
 */
interface Student {
  // 主键
  id: number;
  // 用户名
  name: string;
  // 性别
  sex: number;
  // 用户名
  age: number;
  // 创建时间
  createTime: Date;
  // 更新时间
  updateTime: Date;
  // 是否删除(0-未删, 1-已删)
  isDeleted: number;
}

最后将所有生成的结果放到generateVO对象后返回给前端。

相关推荐
freexyn4 小时前
Matlab自学笔记四十五:日期时间型和字符、字符串以及double型的相互转换方法
开发语言·笔记·matlab
pro_or_check6 小时前
笔记,如何区分大端、小端?
笔记
Rousson6 小时前
硬件学习笔记--34 GB/T17215.321相关内容介绍
网络·笔记·学习
懒洋洋爱睡觉8 小时前
考研计算机组成原理——零基础学习的笔记
笔记·学习·考研
doubt。11 小时前
【BUUCTF】[GXYCTF2019]BabySQli
网络·数据库·笔记·sql·mysql·安全·web安全
CV金科11 小时前
基础科学——高等数学简洁笔记-第一章第一节(函数----上)
笔记·学习·考研·学习方法·高等数学·简洁
APItesterCris14 小时前
如何监控和防范小红书笔记详情API的安全风险?
网络·笔记·安全
bohu8315 小时前
opencv笔记1
人工智能·笔记·opencv
正小安18 小时前
汇编语言:基于x86处理器考前笔记 | 第九章 字符串和数组
笔记