本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
4ye带来主题月的最后一篇文章啦~ ψ(._. )>
本篇文章分为两部分,第一部分为 easymock的安装,第二部分通过一个小项目( Springboot2+Quartz+MybatisPlus+easymock )来实现对 easymock 的使用。
easy-mock-docker官网
直接来到官网看看😄
easy-mock-docker官方地址:github.com/easy-mock/e…
安装步骤如图:
docker-compose安装
这个安装比较简单,执行下面三个步骤就完事了😀
docker-compose官网地址: docs.docker.com/compose/ins…
安装步骤如下:✌
下载docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
赋予权限
sudo chmod +x /usr/local/bin/docker-compose
查看版本
docker-compose --version
配置文件
准备好下面两个配置文件。😄
docker-compose.yml
博主把 easymock 相关文件映射到 /home/ryzeyang/easymock目录下,小伙伴们可以修改成自己的😄
version: '3'
services:
mongodb:
image: mongo:3.4.1
volumes:
# ./data/db 数据库文件存放地址,根据需要修改为本地地址
- '/home/ryzeyang/easymock/data/db:/data/db'
networks:
- easy-mock
restart: always
redis:
image: redis:4.0.6
command: redis-server --appendonly yes
volumes:
# ./data/redis redis 数据文件存放地址,根据需要修改为本地地址
- '/home/ryzeyang/easymock/data/redis:/data'
networks:
- easy-mock
restart: always
web:
image: easymock/easymock:1.6.0
command: /bin/bash -c "npm start"
ports:
- 7300:7300
volumes:
# 日志地址,根据需要修改为本地地址
- '/home/ryzeyang/easymock/logs:/home/easy-mock/easy-mock/logs'
# 配置地址,请使用本地配置地址替换
- '/home/ryzeyang/easymock/production.json:/home/easy-mock/easy-mock/config/production.json'
networks:
- easy-mock
restart: always
networks:
easy-mock:
production.json
这是根据官网提示修改好了的版本。😋
{
"port": 7300,
"host": "0.0.0.0",
"pageSize": 30,
"proxy": false,
"db": "mongodb://mongodb/easy-mock",
"unsplashClientId": "",
"redis": {
"keyPrefix": "[Easy Mock]",
"port": 6379,
"host": "redis",
"password": "",
"db": 0
},
"blackList": {
"projects": [],
"ips": []
},
"rateLimit": {
"max": 1000,
"duration": 1000
},
"jwt": {
"expire": "14 days",
"secret": "shared-secret"
},
"upload": {
"types": [".jpg", ".jpeg", ".png", ".gif", ".json", ".yml", ".yaml"],
"size": 5242880,
"dir": "../public/upload",
"expire": {
"types": [".json", ".yml", ".yaml"],
"day": -1
}
},
"ldap": {
"server": "",
"bindDN": "",
"password": "",
"filter": {
"base": "",
"attributeName": ""
}
},
"fe": {
"copyright": "",
"storageNamespace": "easy-mock_",
"timeout": 25000,
"publicPath": "/dist/"
}
}
启动
创建配置文件中对应logs文件夹(不然后面跑起来会报权限问题)
如:Error: EACCES: permission denied
可以通过xftp将上面的配置文件上传到easymock目录下,然后执行下面的命令启动docker-compose up,这样不会在后台运行,然后你就可以看到项目是否成功跑起来了🐷
地址:http://192.168.80.128:7300
注意!connect EHOSTUNREACH 错误
这是因为我们是通过network去实现容器间的互联,这也是为什么配置里要改成mogodb和redis,而不能用localhost🐷
这两个名字其实就是我们dockerfile文件中,services下的服务名称
简单粗暴的方法如下:
如果启动不了!注意查看下防火墙!!
遇上这种情况,直接关闭防火墙sudo systemctl stop firewalld.service就可以了😄
关闭防火墙后需要重启docker systemctl restart docker.service
后台运行docker-compose up -d
访问地址:http://192.168.80.128:7300 换成自己的ip即可😁
效果如下
环境搭好后,我们就可以来 mock 数据啦,如下!😄
Springboot2+Quartz+MybatisPlus+easymock
主要功能:
通过easymock模拟数据,使用restTemplate去获取这些mock数据,结合Jackson将json转换成实体类,利用 MybatisPlus 批量存储数据, 通过 Quartz 实现一个定时 job ,重复执行上面的步骤。
帮助小伙伴们快速熟悉这个MP的使用和了解下Easymock😄
这事其实是发生在 S10 那天,那会在研究 Mysql 的 Innodb 索引这些 ~ 一边看着比赛,一边想着造点乱七八糟的数据填下DB 并尝试下这个 MybaitsPlus 和用这个 easymock 去 mock 些数据😝
Mysql
看了下时间,有两百多万条了~
建表Sql以下面这一份为主! 其他文章里忘了改了(直接使用了测试时的,有些不一样)
-- 创建user表
CREATE TABLE `test_user` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`user_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户ID',
`user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名称',
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '手机号码',
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邮箱',
`ip` varbinary(4) NOT NULL COMMENT 'IP',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`update_time` datetime(0) NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
Easymock
数据格式如下图:
点击预览可以看到下图:
Json格式文本
这里500-2000 主要是根据自己的机器去配置的,记得easymock中超时时间是1s来着好像,设置太大可能会超时😱
{
"data|500-2000": [{
"userId": '@guid',
"userName": '@cname',
"phone": /^1[385][1-9]\d{8}/,
"email": "@email",
"ip": "@ip",
"createTime": "@datetime('yyyy-MM-dd HH:mm:ss')"
}]
}
主要代码
Job概要
通过 RestTemplate 去获取 mock 数据,使用 Jackson 解析获取 User 信息并反序列化成对象,注意这里 User 实体的 createTime 属性是 LocalDateTime ,需要加上那两行代码! 否则 Jackson无法帮我们完成这个反序列化。
package com.java4ye.demo.job;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.java4ye.demo.entity.User;
import com.java4ye.demo.service.IUserService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.util.StopWatch;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* @author Java4ye
* @date 2021/1/11 23:16
* @微信公众号: Java4ye
* @GitHub https://github.com/RyzeYang
* @博客 https://blog.csdn.net/weixin_40251892
*/
@Slf4j
public class GetMockUserJob extends QuartzJobBean {
@Autowired
RestTemplate restTemplate;
@Autowired
IUserService userService;
@SneakyThrows
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobKey key = jobExecutionContext.getJobDetail().getKey();
log.info("GetMockUserJob start: ");
ResponseEntity<String> forEntity = restTemplate.getForEntity("http://192.168.80.128:7300/mock/5f8c1175994a570020e4dfe4/user/arry#!method=get", String.class);
HttpStatus statusCode = forEntity.getStatusCode();
if (statusCode.is2xxSuccessful()) {
String body = forEntity.getBody();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(body);
JsonNode data = jsonNode.get("data");
System.out.println(data);
// LocalDateTime 的解决方案
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);
List<User> users = objectMapper.readValue(data.toString(), javaType);
StopWatch stopWatch = new StopWatch("save mock users");
stopWatch.start("save mock users");
// 插入一个用户试试
User user = users.get(0);
userService.save(user);
// 批量插入用户
// userService.saveBatch(users,5000);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
}
}
UserMapper 文件
重写insert方法,主要是为了 自定义 IP 字段 INET6_NTOA(ip)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java4ye.demo.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.java4ye.demo.entity.User">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="user_id" jdbcType="VARCHAR" property="userId" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.java4ye.demo.entity.User">
<result column="ip" jdbcType="VARBINARY" property="ip"/>
</resultMap>
<sql id="Base_Column_List">
id, user_id, user_name, phone, email, create_time, update_time
</sql>
<sql id="Blob_Column_List">
INET6_NTOA(ip)
</sql>
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.java4ye.demo.entity.User" useGeneratedKeys="true">
insert into test_user (user_id, user_name, phone,
email, create_time, update_time,
ip)
values (#{userId,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR},
#{email,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP},
INET6_ATON(#{ip,jdbcType=VARBINARY}))
</insert>
</mapper>
运行效果
插入单条数据
批量插入
可以看到这里插入 873 个用户用了 1781ms
项目地址:(感兴趣的小伙伴可以去看下~ 有帮助的话记得给个 star 哦 ~😝 谢谢支持!)
GitHub项目地址 : github.com/RyzeYang/sp…
我是 4ye 我们下期再见啦 ヾ( ̄▽ ̄)ByeBye
欢迎关注,交个朋友呀!! ( •̀ ω •́ )y
嘿嘿 喜欢就支持下啦 😋
让我们开始这一场意外的相遇吧!~
欢迎留言!谢谢支持!ヾ(≧▽≦*)o