{"id":18401632,"url":"https://github.com/linyimin0812/mybatis-sql-viewer","last_synced_at":"2025-04-03T03:12:24.984Z","repository":{"id":52852260,"uuid":"453771731","full_name":"linyimin0812/mybatis-sql-viewer","owner":"linyimin0812","description":"convert mybatis xml to sql statement; mybatis param mock; sql specification check; sql index check; sql execution; sql stress; mybatis sql scan","archived":false,"fork":false,"pushed_at":"2024-06-09T08:02:57.000Z","size":18164,"stargazers_count":173,"open_issues_count":26,"forks_count":36,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T08:37:47.153Z","etag":null,"topics":["intellij-plugin","java","mybatis","mysql","sql"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linyimin0812.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-30T18:54:06.000Z","updated_at":"2025-03-12T08:45:45.000Z","dependencies_parsed_at":"2024-06-09T09:23:02.246Z","dependency_job_id":"039f09b1-4a76-40b3-987a-d35d81275500","html_url":"https://github.com/linyimin0812/mybatis-sql-viewer","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyimin0812%2Fmybatis-sql-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyimin0812%2Fmybatis-sql-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyimin0812%2Fmybatis-sql-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyimin0812%2Fmybatis-sql-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linyimin0812","download_url":"https://codeload.github.com/linyimin0812/mybatis-sql-viewer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246927839,"owners_count":20856198,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["intellij-plugin","java","mybatis","mysql","sql"],"created_at":"2024-11-06T02:39:22.967Z","updated_at":"2025-04-03T03:12:24.961Z","avatar_url":"https://github.com/linyimin0812.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![plugin](https://img.shields.io/badge/IntelliJ%20IDEA%20Plugins-000000?logo=IntelliJ-idea\u0026logoColor=white)](https://plugins.jetbrains.com/plugin/18713-mybatis-sql-viewer)\n[![license](https://img.shields.io/github/license/linyimin0812/mybatis-sql-viewer)](https://github.com/linyimin0812/mybatis-sql-viewer)\n[![Downloads](https://img.shields.io/jetbrains/plugin/d/18713-mybatis-sql-viewer)](https://plugins.jetbrains.com/plugin/18713-mybatis-sql-viewer)\n[![Version](https://img.shields.io/jetbrains/plugin/v/18713.svg?label=version)](https://plugins.jetbrains.com/plugin/18713-mybatis-sql-viewer)\n[![codecov](https://codecov.io/gh/linyimin-bupt/mybatis-sql-viewer/branch/master/graph/badge.svg?token=HIN7SU9HH5)](https://codecov.io/gh/linyimin-bupt/mybatis-sql-viewer)\n\n[中文](README.md) |\n[ENGLISH](README_EN.md)\n\n# 1. 简介\n\n虽然写了很久的CRUD，但是依旧觉得写好CRUD是一件非常难且麻烦的事情，以下的情况在开发过程中应该都遇到过：\n\n- SQL的编写需要细心，写错了SQL字段或者表名称，修改完要重启(几分钟过去了)\n- SQL编写好后进行测试时，造数据也好麻烦，特别是还存在表关联的情况，数据内容不真实，还容易超出字段长度，让人抓狂\n- SQL好不容易能跑了，又会有以下的疑问\n  - 符不符合SQL开发规范？\n  - 是否能命中索引？又可能命中哪个索引？\n  - 日常环境数据太少，如何模拟SQL在生产环境下运行的真实情况？\n  - 性能怎么样，最大TPS可以达到多少？数量大时是否会存在慢SQL？\n  - TP99/TP90、最大RT/平均RT、平均TPS是多少呢？\n\n对于使用Mybatis的开发者还会存在这些问题：\n\n- Mapper接口方法和XML标签不对应，修改完要重启(又几分钟过去了)\n- XML中多写了一个逗号或者分号，又没有错误提示，接口测试调用时才发现，修改完又又要重启(好多个几分钟过去了)\n- 这个Mapper接口对应的是哪个XML文件？找找十几秒过去了\n- 这个XMl文件对应的是哪个Mapper接口？找找十几秒又过去了\n- 这个项目中有多少个XML文件？有多少SQL语句？里面是否存在慢SQL？是否都符合开发规范？\n\n![普通开发流程](./docs/dev_process.svg)\n\n按照这种开发模式，需要重启好多次应用，对于每次启动都需要几分钟的应用来说开发体验简直就是灾难。基于上述的问题，开发了mybatis-sql-viewer插件，基于此插件可以实现以下能力而不需要启动应用：\n\n![mybatis-sql-viewer能力](./docs/mybatis-sql-viewer_function.svg)\n\n基于此插件以上的问题在**编码阶段**即可解决：\n\n- SQL的编写好麻烦，写错了SQL字段或者表名称，修改完需要重启 --\u003e **语法校验**\n- SQL编写好后进行测试时，造数据麻烦，特别是存在表关联的情况，数据内容不真实，容易超出字段长度报错 --\u003e **多种数据mock方式，自动关联**\n- SQL好不容易跑起来了，又会有以下的疑问：\n  - 符不符合SQL开发规范？ --\u003e **SQL规范检查**\n  - 是否能命中索引，可能命中哪个索引？ --\u003e **SQL索引检查\u0026SQL执行计划**\n  - 日常环境数据量太少，如何模拟SQL在生产环境下运行的真实情况？ --\u003e **支持大批量数据mock**\n  - 性能怎么样，最大TPS可以达到多少？数量大时是否会存在慢SQL？ --\u003e **SQL语句压测，结果一目了然**\n\n基于此插件可以提高CRUD的效率及SQL质量，开发流程可以转换为如下模式：\n\n![基于mybatis-sql-viewer插件的开发流程](./docs/mybatis-sql-viewer_dev_process.svg)\n\n上述的规约均来自《阿里巴巴Java开发手册》中的MySQL数据库章节。\n\n# 2. 安装\n\n- **IDEA中安装:**\n    - \u003ckbd\u003ePreferences(Settings)\u003c/kbd\u003e \u003e \u003ckbd\u003ePlugins\u003c/kbd\u003e \u003e \u003ckbd\u003eMarketplace\u003c/kbd\u003e \u003e \u003ckbd\u003eSearch\u003cb\u003e\"mybatis sql viewer\"\u003c/b\u003e\u003c/kbd\u003e \u003e \u003ckbd\u003eInstall\u003c/kbd\u003e\n\n- **手动安装:**\n    - 在[releases](https://github.com/linyimin0812/mybatis-sql-viewer/releases)页面中下载最新版本的zip文件\n    - \u003ckbd\u003ePreferences(Settings)\u003c/kbd\u003e \u003e \u003ckbd\u003ePlugins\u003c/kbd\u003e \u003e \u003ckbd\u003e⚙️\u003c/kbd\u003e \u003e \u003ckbd\u003eInstall plugin from disk...\u003c/kbd\u003e -\u003e 选择下载的文件安装\n\n# 3. 使用\n\n**因为需要拉取数据库表的元数据信息、执行SQL，所以使用前需要配置一下数据源。**\n\n**因为需要拉取数据库表的元数据信息、执行SQL，所以使用前需要配置一下数据源。**\n\n**因为需要拉取数据库表的元数据信息、执行SQL，所以使用前需要配置一下数据源。**\n\n支持多数据源配置，点击「datasource」按钮即可完成数据源的创建、选择、删除、测试。\n\n![](./docs/datasource.jpg)\n\n## 3.1 模式\n\n此插件有两种模式：mybatis模式和非mybatis模式。差别在于mybatis模式支持以下功能：\n\n- mapper接口方法参数mock\n  - 随机参数\n  - 默认参数\n  - 自定义参数\n- mapper接口/方法跳转XML文件([可配置](#4-配置))\n- XML文件跳转mapper接口/方法([可配置](#4-配置))\n- 基于mock参数将mapper接口方法的xml转换成真实SQL\n- 按照文件/项目维度扫描XML文件，并生成对应的真实SQL语句，并进行规约/索引相关校验\n\n### 3.1.1 非mybatis模式\n\n将`mybatis mode`的勾选框关闭即可使用`非mybatis模式`，然后在「statement」Tab左栏手写SQL即可。\n\n![](./docs/mybatis-mode.jpg)\n\n### 3.1.2 mybatis模式\n\n将`mybatis mode`的勾选框选中即可使用`mybatis模式`，`mybatis模式`主要添加了mapper接口方法参数mock、文件跳转及mybatis文件扫描的功能。\n\n在mapper接口或XML文件中点击「sql」图标，即可生成mapper方法参数随机值，如果对生成的随机不满意或不满足条件，可以手动修改进行自定义。然后点击「statement」Tab即可使用该参数将mybatis的xml实现转换成真实的SQL语句。\n\n![随机参数](./docs/param_random.jpg)\n\n### 3.1.3 mybatis sql扫描\n\n支持文件和项目两个维度扫描。\n\n#### 3.1.3.1. 文件维度扫描\n\n点击`\u003cmapper namespace=\"xxx.xxx.xxx\"\u003e`或者`namespace`对应的mapper接口旁边的「sql」图标即可完成文件维度mybatis sql的扫描\n\n![文件维度扫描](./docs/scan_file.jpg)\n\n#### 3.1.3.2 项目维度\n\n点击「mybatis sql scan」即可进行项目维度mybatis sql的扫描\n\n![项目维度扫描](./docs/scan_project.jpg)\n\n扫描结果左侧是mybatis文件的namespace（对于mapper接口名）及其下的方法名，点击具体的方法，右侧产生其对应的SQL语句，并会对该SQL语句进行规约检查、索引检查并输出此SQL语句的的执行计划\n\n**图标说明**\n\n![](./docs/major.svg)：表示SQL规约检查和索引检查均符合要求的SQL语句\n\n![](./docs/not_meet_spec.svg)：表示SQL规约检查不符合要求的SQL语句\n\n![](./docs/full_text_search.svg)：表示索引检查不符合要求的SQL语句，可能存在全表扫描(含索引的全表扫描)\n\n![](./docs/error.svg)：表示生成的SQL语句存在问题：可能是SQL编写错误，参数错误，数据库连接错误等\n\n**可通过单选框选择对应的条件进行过滤**\n\n- all：所有语句\n- compliance with spec：符合SQL规约要求的SQL语句\n- does not meet spec：不符合SQL规约的要求的SQL语句\n- full table scan：存在全表扫描的SQL语句\n- error：存在错误的SQL语句，可能是SQL编写错误，参数错误，数据库连接错误等\n\n\n## 3.2 SQL语句\n\n### 3.2.1. 语法校验\u0026规约检查\n\n对于「非mybatis模式」需要左栏编写SQL语句，「mybatis」模式则需要在mapper接口或XML文件中点击「sql」图标生成SQL，右栏自动进行语法校验和规规约校验\n\n1. **SQL语法校验**\n\n![statement效果之语法校验](./docs/sql_statement_syntax.jpg)\n\n2. **规约校验**\n\n![statement效果之规约检查](./docs/sql_statement_rule.jpg)\n\n### 3.2.2. SQL执行\n\n点击「result」tab后会自动执行「statement」Tab中的SQL语句。执行结果由3部分组成：执行信息、执行计划及执行结果。\n\n1. 执行信息包含：执行的语句、执行该条语句的耗时、返回的记录数及表中记录总数\n2. 执行计划：EXPLAIN对应的结果\n3. 执行结果：结果表格，默认只返回100条记录（只有SELECT语句有该信息）\n\n![result效果](./docs/result.jpg)\n\n### 3.2.3. SQL压测\n\n点击「stress」Tab进行压测配置，配置页面如下：\n\n![stress配置](./docs/stress_config.jpg)\n\n**配置说明**\n\n1. 值类型由两种方式组成：\n   1. `use sql directly`：表示直接使用「statement」Tab中的SQL语句进行压测\n   2. `configure parameters`：表示对「statement」Tab中的SQL语句的条件进行参数配置。\n2. 流量模型也是由两种方式组成（与并发数有关）：\n   1. `increase in a constant rate`：并发数按照固定速率增长，增长速率由「递增时长」指定\n   2. `fixed concurrent number`：直接按照指定并发数进行压测\n3. 递增时长：指定并发数的增长速率，单位为秒\n4. 并发数：同时执行SQL语句的线程数\n5. 压测时长：指定压测时间，单位为分钟，**因为压测的指标数据直接存在内存中，应该避免压测时间过长造成Idea OOM**\n\n配置完成后，点击「stress」按钮即可进行压测，并自动跳转到压测报告「report」Tab\n\n**压测报告**\n\n压测报告中主要包含指标：\n\n- 请求成功率\n- TP99\n- TP90\n- 最大RT\n- 平均RT\n- 最大TPS\n- 平均TPS\n- 并发数\n- 异常数\n- 总请求数\n\n图表包含：\n- 请求成功率\n- 平均RT\n- TPS\n\n![压测报告](./docs/stress_report.jpg)\n\n## 3.3 SQL表\n\n点击「table」Tab时会对「statement」Tab中的SQL语句进行解析，提取出表名称，然后每个表作为一个Tab。如以下语句：\n\n```mysql\nSELECT\n    state\nFROM\n    CITY\nWHERE\n    country_name IN (\n        SELECT\n            name\n        FROM\n            COUNTRY\n        WHERE\n            id IN (1, 2, 3)\n    )\n```\n\nSQL语句中包含了两个表：`CITY`和`COUNTRY`，所以会产生两个Tab，如下图所示：\n\n![specify table tab](./docs/specify_table.jpg)\n\n### 3.3.1. 字段\n\n1. 左栏显示表的字段信息：字段名称、类型、是否可为NULL、默认值、索引、注释说明等信息\n2. 右栏显示对表进行建表规约检查的结果：如表名、字段名是否包含大写字母或特殊字符等检查\n\n![schema tab](./docs/schema_tab.jpg)\n\n### 3.3.2. 索引\n\n1. 左栏显示表的索引信息\n2. 右栏显示对索引进行规约检查的结果\n\n![schema tab](./docs/schema_index.jpg)\n\n### 3.3.3. 数据mock\n\nmock表数据，支持批量数据mock，左栏进行mock数据类型配置，右栏显示mock结果\n\n**mock规则**\n\n左栏表单中「Mock Type」和「Mock Value」进行mock配置。初始化时，已经按照字段类型设置了默认的配置，可以按照需求进行修改。支持多种mock数据规则：\n\n- random：随机值\n  - string\n  - name：姓名\n  - datetime：形如：2023-01-01 00:00:00\n  - integer\n  - decimal\n  - date：形如2023-01-01\n  - timestamp\n  - time：形如18:00:00\n  - year：形如2023\n  - city\n  - url\n  - email\n  - ip\n  - university\n  - phone\n- lexicon：自定义词库\n- database：数据库，需要填写`table.field`\n- increment：递增\n- fixed：固定值\n- regex：正则\n- none：不进行mock，生成insert语句时不包含此字段\n\n\n**词库创建**\n\n点击「lexicon」按钮，即可进行词库的创建\n\n![lexicon create](./docs/lexicon_create.jpg)\n\n**mock数据预览**\n\n配置好mock配置后，可以点击「preview」按钮进行mock数据的预览，默认会生成50条数据\n\n![mock preview](./docs/mock_preview.jpg)\n\n**mock数据**\n\n预览数据符合要求后，点击「mock」按钮完成数据的插入，默认插入100条数据，通过修改「Mock Rows」的值指定mock记录数，经测试，插入10w条数据花费时间在10秒内，所以可以进行大批量数据mock。\n\n![mock result](./docs/mock_result.jpg)\n\n**mock数据清理**\n\nmock数据完成后，会存储主键id的范围（持久化存储到本地文件），在对SQL语句进行压测完成后，可以进行清理，避免污染日常真实的测试数据。点击「Clean」按钮即可完成清理工作\n\n![mock clean](./docs/mock_clean.jpg)\n\n# 4. 配置\n\n相关配置：\u003ckbd\u003ePreferences(Settings)\u003c/kbd\u003e \u003e \u003ckbd\u003eTools\u003c/kbd\u003e \u003e \u003ckbd\u003eMybatis Sql Viewer\u003c/kbd\u003e\n\n![](./docs/mybatis-sql-viewer-configuration.png)\n\n# 5. 参考\n\n在实现过程中参考了许多非常优秀的项目，拷贝了很多代码，特此感谢。\n\n[1. 阿里云JDBC压测](https://help.aliyun.com/document_detail/327250.html)\n\n[2. SQL Father - 模拟数据生成器（后端）](https://github.com/liyupi/sql-father-backend-public)\n\n[3. Java Mybatis SQL Scanner](https://github.com/q258523454/Java-Mybatis-SQL-Scanner)\n\n[4. 动手撸一个SQL规范检查工具](https://zhuanlan.zhihu.com/p/362200137)\n\n[5. pojo2json](https://github.com/organics2016/pojo2json)\n\n[6. mybatis-3](https://github.com/mybatis/mybatis-3)\n\n# ✨ Contributor\n\n[\u003ckbd\u003e \u003cimg src=\"https://avatars.githubusercontent.com/u/17776713?s=48\u0026v=4\" /\u003e \u003c/kbd\u003e](https://github.com/linyimin0812)\n[\u003ckbd\u003e \u003cimg src=\"https://avatars.githubusercontent.com/u/12124172?s=48\u0026v=4\" /\u003e \u003c/kbd\u003e](https://github.com/clickear)\n\n\n\n# 🤝 为项目添砖加瓦\n\n欢迎提出 Contributions, issues 与 feature requests!\u003cbr /\u003e随时查看 [issues page](https://github.com/linyimin0812/mybatis-sql-viewer/issues).\n\n# 🙏感谢支持\n\n如果这个项目对你产生了一点的帮助，请为这个项目点上一颗 ⭐️\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinyimin0812%2Fmybatis-sql-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinyimin0812%2Fmybatis-sql-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinyimin0812%2Fmybatis-sql-viewer/lists"}