Springboot 结合 easymock 的使用| Java Debug 笔记

851 阅读5分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

4ye带来主题月的最后一篇文章啦~ ψ(._. )>

本篇文章分为两部分,第一部分为 easymock的安装,第二部分通过一个小项目( Springboot2+Quartz+MybatisPlus+easymock )来实现对 easymock 的使用。

easy-mock-docker官网

直接来到官网看看😄

easy-mock-docker官方地址github.com/easy-mock/e…

安装步骤如图:

20201018013459

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

20201018013139

配置文件

准备好下面两个配置文件。😄

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去实现容器间的互联,这也是为什么配置里要改成mogodbredis,而不能用localhost🐷

20201018111646

这两个名字其实就是我们dockerfile文件中,services下的服务名称

20201018112521

简单粗暴的方法如下:

如果启动不了!注意查看下防火墙!!

20201018111303

遇上这种情况,直接关闭防火墙sudo systemctl stop firewalld.service就可以了😄

关闭防火墙后需要重启docker systemctl restart docker.service

后台运行docker-compose up -d

访问地址:http://192.168.80.128:7300 换成自己的ip即可😁

效果如下

20201018133154

环境搭好后,我们就可以来 mock 数据啦,如下!😄

Springboot2+Quartz+MybatisPlus+easymock

主要功能:

通过easymock模拟数据,使用restTemplate去获取这些mock数据,结合Jackson将json转换成实体类,利用 MybatisPlus 批量存储数据, 通过 Quartz 实现一个定时 job ,重复执行上面的步骤。

帮助小伙伴们快速熟悉这个MP的使用和了解下Easymock😄

这事其实是发生在 S10 那天,那会在研究 Mysql 的 Innodb 索引这些 ~ 一边看着比赛,一边想着造点乱七八糟的数据填下DB 并尝试下这个 MybaitsPlus 和用这个 easymock 去 mock 些数据😝

Mysql

看了下时间,有两百多万条了~

image-20210112080516801

建表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

数据格式如下图:

image-20210112081902904

点击预览可以看到下图:

image-20210112082147694

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>

运行效果

插入单条数据

image-20210113224455330

批量插入

可以看到这里插入 873 个用户用了 1781ms

image-20210113224941786

项目地址:(感兴趣的小伙伴可以去看下~ 有帮助的话记得给个 star 哦 ~😝 谢谢支持!)

GitHub项目地址 : github.com/RyzeYang/sp…

我是 4ye 我们下期再见啦 ヾ( ̄▽ ̄)ByeBye

欢迎关注,交个朋友呀!! ( •̀ ω •́ )y

嘿嘿 喜欢就支持下啦 😋

让我们开始这一场意外的相遇吧!~

欢迎留言!谢谢支持!ヾ(≧▽≦*)o