这里简单记录写学习鱼皮sqlfather项目的笔记,以供以后学习。
运行
将前后端项目clone到本地后,修改对应配置文件运行项目。
后端
1.配置好mysql后运行这个sql文件建立对应的表。
2.修改数据库密码
3.修改完后运行启动类即可
- 启动结果
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表为例
- 前段发送请求 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;
}
}
- 然后会进入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对象后返回给前端。