Spring BootとMyBatisの組み合わせで模擬プラットフォームを実現

前の章: 

テストツール: Spring Boot でモックプラットフォームを実現

コードアドレス:

GitHub - 18713341733/mock: Spring Boot と MyBatis の組み合わせはモック プラットフォームの変革を実現します

1. 背景 

読み取りデータは、mysql データベースから読み取るように変更されます。

Spring Bootのバージョンは2.4.4です 

mysqlのバージョンは8.0です

2. デザイン

以前は txt ファイルを直接読み取っていましたが、これからは mysql から直接読み込むようになりました。

この変革の段階では、デザインパターンは一切使用されず、直接の水の流れによって機能が実現されます。

データベースデータ:

 ユーザーが要求した URI に従って、条件としてテーブルに移動してデータをクエリします。同じ URI に複数のデータがある場合、リクエスト パラメータのヒットの重みを比較し、最も重みの高い返されたデータを選択する必要があります。

例:

データ内には、uri が /baidu/search であるデータが 2 つあります。

ウリ 応答内容 パラメータ
/百度/検索 {"type":"タイプ 1","key11":"${random:id:6}","key2":"${random:str:10}","count":3,"person": [{"id":${フック:id}},"name":"張三"},{"id":2,"name":"李思"}],"オブジェクト":{"id" :1,"msg":"オブジェクト内のオブジェクト"}} {"名前=本":1,"分類=言語":5}
/百度/検索 {"type":"タイプ 2","key11":"${random:id:6}","key2":"${random:str:10}","count":3,"person": [{"id":${フック:id}},"name":"張三"},{"id":2,"name":"李思"}],"オブジェクト":{"id" :1,"msg":"オブジェクト内のオブジェクト"}} {"名前=本":1,"分類=数学":4}

データ 1 のパラメータは次のとおりです: {"name=book":1,"classification=Language":5}

データ 2 のパラメータは次のとおりです: {"name=book":1,"classification=Math":4}


ユーザーのリクエストは次のとおりです。

http://127.0.0.1:8081/baidu/search?name=book&classification=Math

データ 1、「name=book」をヒット、重みは 1

データ 2、「name=book」をヒット、重みは 1、「classification=Math」をヒット、重みは 4、データ 2 の合計重みは 1+4=5 です。

5>1 なので、データ 2 の戻り値を取得して返します。

データ2の返されたデータは、ランダムな文字列の置換などの再処理が行われます。

3. データの初期化

1.mockserverという名前のライブラリを作成します

2. テーブル応答を作成する

3. デモンストレーション用にいくつかのデータを挿入します

/*
 Navicat Premium Data Transfer

 Source Server         : 本地- mysql
 Source Server Type    : MySQL
 Source Server Version : 50710
 Source Host           : localhost:3306
 Source Schema         : mockserver

 Target Server Type    : MySQL
 Target Server Version : 50710
 File Encoding         : 65001

 Date: 26/07/2023 16:41:48
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for response
-- ----------------------------
DROP TABLE IF EXISTS `response`;
CREATE TABLE `response` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uri` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `response_content` text COLLATE utf8mb4_unicode_ci,
  `params` text COLLATE utf8mb4_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ----------------------------
-- Records of response
-- ----------------------------
BEGIN;
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (1, '/baidu/search', '{\"type\":\"sougou_1\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\",\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=book\":1,\"classification=Language\":5}');
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (2, '/baidu/search', '{\"type\":\"sougou_2\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\",\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=book\":1,\"classification=Math\":4}');
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (3, '/sougou/search', '{\"type\":\"sougou_3\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\",\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=sougou\":2,\"classification=Math\":4}');
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (4, '/sougou/search', '{\"type\":\"sougou_4\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\",\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=sougou\":2,\"classification=Language\":5}');
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (5, '/taobao/search', '{\"type\":\"类型一\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\"},\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=lisi\":1,\"classification=Math\":4}');
INSERT INTO `response` (`id`, `uri`, `response_content`, `params`) VALUES (7, '/taobao/search', '{\"type\":\"张三\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\"},\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}', '{\"name=zhangsan\":1,\"classification=Math\":4}');
COMMIT;

4. 関連インターフェース

4.1 モックデータの作成

POSTリクエスト

URL:http://127.0.0.1:8081/addResponse

リクエストの本文は json 形式です。

{
    "uri":"/taobao/search",
    "params":"{\"name=zhangsan\":1,\"classification=Math\":4}",
    "response_content":"{\"type\":\"张三\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\"},\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}"
}

知らせ:

リクエスト本文内の二重引用符はバックスラッシュでエスケープする必要があります

4.2 モックリクエスト

GET请求URL:http://127.0.0.1:8081/baidu/search?name=book&classification=Language

戻り値:

{
    "type": "sougou_1",
    "key11": "816986",
    "key2": "npUtLZWAnu",
    "count": 3,
    "person": [
        {
            "id": "${hook:id}",
            "name": "张三"
        },
        {
            "id": 2,
            "name": "李四"
        }
    ],
    "object": {
        "id": 1,
        "msg": "对象里的对象"
    }
}

4.3 モックデータの変更

役職

URL:http://127.0.0.1:8081/updateResponse

リクエスト本文のJSON

{
    "id":5,
    "uri":"/taobao/search",
    "params":"{\"name=lisi\":1,\"classification=Math\":4}",
    "response_content":"{\"type\":\"类型一\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\"},\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}"
}

知らせ:

リクエスト本文内の二重引用符はバックスラッシュでエスケープする必要があります

4.4 モックデータの削除

IDで削除

役職

http://127.0.0.1:8081/deleteResponse

リクエスト本文のjson

{
    "id":6
}

4.5 クエリモックリスト

得る

http://127.0.0.1:8081/allResponse

5. 戻り値データの処理

{
    "uri":"/taobao/search",
    "params":"{\"name=zhangsan\":1,\"classification=Math\":4}",
    "response_content":"{\"type\":\"张三\",\"key11\":\"${random:id:6}\",\"key2\":\"${random:str:10}\",\"count\":3,\"person\":[{\"id\":\"${hook:id}\"},\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}],\"object\":{\"id\":1,\"msg\":\"对象里的对象\"}}"
}

response_content はユーザーに返されるデータです。

${random:id:6} は 6 桁の乱数を生成します

${random:str:10} は 10 桁のランダムな文字列を生成します

6. MyBatisを適用する

6.1 依存関係

  1. Spring Boot プロジェクトに必要な依存関係を追加します。プロジェクトの pom.xml ファイルに、次の依存関係を追加します。
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
<dependency>

6.2 データベース接続の構成

データベース接続を構成します。またはapplication.propertiesファイルapplication.ymlでデータベース接続情報を構成します。次に例を示します。

application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=dbuser
spring.datasource.password=dbpassword

application.yml:

server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mockserver?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

MyBatis マッパー インターフェイスと対応する SQL マッピング ファイルを作成します。パッケージ構造内にマッパー インターフェイスを作成し、そのインターフェイスに対して実行する必要があるデータベース操作を定義します。同時に、マッパー インターフェイスに対応する XML ファイルをリソース ディレクトリに作成し、SQL ステートメントとクエリ ロジックを保存します。

@MapperScan アノテーションを Spring Boot メインクラスに追加します。Spring Boot メインクラスに @MapperScan アノテーションを追加し、MyBatis マッパー インターフェイスをスキャンするパッケージ パスを指定します。

6.3 インスタンス層エンティティ

必要なインスタンスが保存されます。

MockOnlyResponse はデータベース内の応答テーブルのデータに対応します 

このクラスのデータを読み取るメソッドも提供します。

package com.example.mockserver.entity;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.HashMap;
import java.util.Map;


@Data
@NoArgsConstructor
public class MockOnlyResponse {
    private String response_content;
    private String params;

    public MockOnlyResponse(String response_content,String params) {
        this.response_content = response_content;
        this.params = params;
    }

    public Map<String, Integer> getMapParams() {
        // 将接口拿到的数据库中的请求体,设置为字典
        return getMap(this.params);

    }

    // 将字符串直接转成字典
    public Map<String, Integer> getMap(String jsonString) {
//        String jsonString = "{\"name=book\":1,\"classification=Language\":5}";

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Integer> dictionary = objectMapper.readValue(jsonString, Map.class);

            return dictionary;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

}

6.4 mybatis のマッパー層

インターフェース:

OnlyResponseMapper

package com.example.mockserver.mapper;


import com.example.mockserver.entity.MockOnlyResponse;
import org.springframework.stereotype.Repository;
import java.util.List;

import org.apache.ibatis.annotations.Select;


@Repository
public interface OnlyResponseMapper {
    @Select("select r.response_content,r.params from response r where uri = #{uri}")
    List<MockOnlyResponse> findByUri(String uri);
}

SQLを実行し、uriを介してデータをクエリします。

6.5スプリングブートサービス層

サービスインターフェイス、OnlyResponseService

package com.example.mockserver.service;

import com.example.mockserver.entity.MockOnlyResponse;



import java.util.List;

public interface OnlyResponseService {
    List<MockOnlyResponse> findByUri(String uri);
}

サービス実装クラス、ResponseServiceImpl

package com.example.mockserver.service.imp;
import com.example.mockserver.entity.MockOnlyResponse;
import com.example.mockserver.mapper.OnlyResponseMapper;
import com.example.mockserver.service.OnlyResponseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ResponseServiceImpl implements OnlyResponseService {

    @Autowired
    private OnlyResponseMapper onlyMapper;

    @Override
    public List<MockOnlyResponse> findByUri(String uri) {
        return onlyMapper.findByUri(uri);
    }

}

mybatis のマッパー インターフェイスを Spring Boot サービス実装クラスに挿入しました。

6.6 コントローラー層

レスポンスコントローラー

package com.example.mockserver.controller;
import com.example.mockserver.entity.MockOnlyResponse;
import com.example.mockserver.service.OnlyResponseService;
import com.example.mockserver.util.ArrayUtil;
import com.example.mockserver.util.ReplaceRandomUtil;
import lombok.extern.slf4j.Slf4j;

import com.example.mockserver.model.MockContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class ResponseController {
    @Autowired
    private OnlyResponseService onlyResponseService;

    @Autowired
    private HttpServletRequest request;


    @RequestMapping("/**")
    public String doMock() throws IOException {

        log.info("请求的URI---------:"+request.getRequestURI());
        log.info("请求IP---------:"+request.getRemoteAddr());
        log.info("请求的参数---------:"+request.getParameterMap());


        // 将获取的用户数据 ip 参数 URI ,存储到 mockContext 这个类里
        MockContext mockContext = MockContext.builder()
                .requestIp(request.getRemoteAddr()) // 获取ip
                .requestParams(getParams(request.getParameterMap()))
                .requestURI(request.getRequestURI()) // 获取请求的URI
                .build();

        // [name=zhangsan, classification=Language]
        List<String> userParamStringList = mockContext.getParamStringList();
        Integer totalNum = 0;
        String response = "";
        System.out.println(userParamStringList);



        // 开始遍历
        List<MockOnlyResponse> mockOnlyResponseList = onlyResponseService.findByUri(mockContext.getRequestURI());
        System.out.println(mockOnlyResponseList);
        for (MockOnlyResponse mockOnlyResponse : mockOnlyResponseList) {
            Integer num = 0;
            for(String str:userParamStringList){
                // 字典
                Map<String, Integer> mapParams = mockOnlyResponse.getMapParams();
                if (mapParams.containsKey(str)) {
                    num += mapParams.get(str);
                }
            }
            if(num>totalNum){
                totalNum = num;
                response = mockOnlyResponse.getResponse_content();
            }
        }
        // 随机数字/字符串处理
        response = ReplaceRandomUtil.replaceRandomFields(response);
        return response;

    }

    // 获取用户的传参,value是一个数组。这里为了将来处理方便,我们将这数组转成一个字符串。
    // 我们默认,这个数据的长度是1,那我们只需要取出来数组的第一个值就可以了。
    public Map<String,String> getParams(Map<String,String[]> parameterMap){
        Map<String,String> params = parameterMap.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> ArrayUtil.getFirst(e.getValue())));
        return params;

    }
}

6.7 アプリケーション起動層 MockServerApplication

package com.example.mockserver;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
@MapperScan(basePackages = "com.example.mockserver.mapper")
public class MockServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(MockServerApplication.class, args);
    }

}


プロジェクトの起動レイヤーにマッパー スキャンを追加する必要があります。

mybatis の単純な使用と比較して、スプリング ブート アプリケーション mybatis には、mybatis の全体的な構成ファイルが不足しています。

ここにパッケージ名を入力します。@MapperScan(basePackages = 

7. データ処理

データ処理ロジックは主に ResponseController 内にあり、まだカプセル化されていません。

論理:

1. ユーザーのリクエスト URI とリクエストボディを取得します。

2. ユーザーのリクエスト本文をマップに変換します。

3. リクエスト URI に従って、データベースにアクセスしてデータを取得します。戻り値はリストです。

4. リストを走査するには、最大の重みを持つ戻り値のデータを取得します。

5. 取得したデータを加工したり、ランダムな文字列を加工したりする。

8. デモンストレーション

9. 関連記事

Spring Boot アプリケーション mybatis_springboot mybatis debug_Do テストニャーソースのブログ - CSDN ブログ

 

おすすめ

転載: blog.csdn.net/qq_39208536/article/details/131892781