Kaitoven Lab - Kaitoven Chen
type: channel
link: https://www.kaitoven.com/author/1/
description: Kaitoven Chen
items: 网站英文版本连接中...
items: 增加生成二维码的容错率
items: 多线程爬取图片(Python)
items: 代码生成网站专属二维码
items: 小鱼特效以及回到顶部
items: [研究学习日记] 当 Segment Anything 大模型遇上医学 X 光：从零样本到动态提示工程的探索
items: MyBatis中实现多层嵌套映射
items: MyBatis中实现一对多映射
items: 企微bot定时推送教程
items: 分页实现示例

网站英文版本连接中...
type: item
date: 2026-04-10T09:22:00+08:00
description: 有成本，目前暂停英文版的制作...

增加生成二维码的容错率
type: item
date: 2024-10-14T02:33:00+08:00
description: 叙述 书接上回：代码生成网站专属二维码 有宝宝反应，在有遮挡的情况下（怎么会遮挡呢？这种情况怎么能出现？我实在没考虑这种情况，但是为了更好的用户体验，即使这是一张小小的二维码图片也要根据反馈使它更完美）二维码扫不出来，好了，已解决。全部的代码可以前往 我的colab 查看。 为了保证二维码在不完全显示的情况下能够被成功扫描，不说了，直接上代码 下面是针对这些调整的改进代码： 代码 import qrcode from PIL import Image, ImageEnhance, ImageSequence # 生成二维码并提高容错级别 data = "https://www.example.com" # 二维码内容 qr = qrcode.QRCode( version=2, # 适中的二维码大小 error_correction=qrcode.constants.ERROR_CORRECT_H, # 高容错率 box_size=10, # 每个二维码格子的像素大小 border=1, # 边框减少 ) qr.add_data(data) qr.make(fit=True) # 生成二维码图片，并转换为 RGBA 模式，支持透明背景 qr_img = qr.make_image(fill='black', back_color='white').convert('RGBA') # 将二维码的白色部分替换为透明 datas = qr_img.getdata() new_data = [] for item in datas: # 将白色 (255, 255, 255) 替换为透明 if item[:3] == (255, 255, 255): # RGB是白色时 new_data.append((255, 255, 255, 0)) # 透明 else: new_data.append(item) qr_img.putdata(new_data) # 打开动态GIF图片 gif_path = "/content/your_dynamic_background.gif" # 替换为你的GIF路径 gif = Image.open(gif_path) # 设置需要的背景图和二维码的尺寸 new_size = (200, 200) # 目标大小，可以根据需要调整 # 调整二维码的大小 qr_img = qr_img.resize(new_size, Image.LANCZOS) # 用于存储处理后的帧 frames = [] # 遍历GIF的每一帧 for frame in ImageSequence.Iterator(gif): # 将每一帧转换为 RGBA 模式 frame = frame.convert('RGBA') # 调节背景图片的透明度，保证背景不过度干扰二维码 alpha = 0.3 # 设置透明度，值越小二维码越清晰，背景越不显眼 enhancer = ImageEnhance.Brightness(frame) frame = enhancer.enhance(alpha) # 调整每一帧的大小与二维码一致 frame = frame.resize(new_size, Image.LANCZOS) # 创建一个半透明的白色蒙版，进一步减少背景干扰 mask = Image.new('RGBA', qr_img.size, (255, 255, 255, 180)) # 半透明白色 # 将蒙版叠加到帧上 frame.paste(mask, (0, 0), mask) # 将二维码叠加到帧上 frame.paste(qr_img, (0, 0), qr_img) # 添加处理后的帧到frames列表中 frames.append(frame) # 保存结果为新的GIF，保留原GIF的帧速率和循环设置 frames[0].save( "qrcode_with_optimized_dynamic_background.gif", save_all=True, append_images=frames[1:], # 添加其他帧 duration=gif.info['duration'], # 使用原始的帧持续时间 loop=gif.info.get('loop', 0) # 保留循环设置 ) 改进点 高容错率：通过设置 error_correction=qrcode.constants.ERROR_CORRECT_H，二维码有 30% 的损坏空间仍然可以被正确识别。这允许部分二维码被遮盖或干扰而不影响扫描效果。 背景透明度调节：通过 alpha = 0.3 减少背景对二维码的干扰，保持二维码在背景上更加清晰。可以根据需要调…

多线程爬取图片(Python)
type: item
date: 2024-10-08T22:25:00+08:00
description: 简述 万圣节快到了，需要一些万圣节主题的图片制作成海报，到网站一张一张下载太过麻烦，就想着实现一个简单的Python爬虫工具来获取万圣节相关的图片，由于一些网站可能会通过robots.txt或其他手段禁止爬虫行为，你应当首先确认该网站是否允许被爬取，爬取内容时应当遵守网站的robots.txt规则以及相关的使用条款，避免非法爬取。我今天要爬取的网站是https://www.istockphoto.com/, 该站是允许爬取的。好了，开始了，可以使用requests和BeautifulSoup来爬取网页内容。另外，istockphoto网站通常会使用JavaScript加载图片，这意味着仅使用requests和BeautifulSoup可能无法抓取动态加载的内容。在这种情况下，可以考虑使用Selenium或Playwright来处理JavaScript渲染。 我今天实现的是基于Selenium的爬虫，它能够访问https://www.istockphoto.com/并查找与“万圣节”相关的图片。 准备：安装Selenium库和ChromeDriver pip install selenium 安装Selenium库, 用于模拟浏览器行为，特别是加载JavaScript内容。 安装一个WebDriver, 我使用的是ChromeDriver（注意控制Chrome浏览器，你需要下载对应版本的ChromeDriver并设置其路径）ChromeDriver的安装不再赘述，下面简短的说一下windows系统的安装与设置吧： 步骤 1: 检查你的Chrome浏览器版本 ChromeDriver的版本必须与已安装的Chrome浏览器版本匹配。 打开Chrome浏览器。 在地址栏中输入 chrome://settings/help，然后按下回车。 你会看到当前的Chrome版本号。 步骤 2: 下载与Chrome版本匹配的ChromeDriver 访问ChromeDriver官网。 查找与你的Chrome浏览器版本匹配的ChromeDriver版本（对于版本 115 及更高版本，）您可以在 Chrome for Testing (CfT) 可用性信息中心查看各个发布渠道（稳定版、Beta 版、开发者版、Canary 版）的最新 ChromeDriver 版本。。 下载适合你操作系统的文件（Windows, Mac, 或 Linux，我用的是win的）。 步骤 3: 安装ChromeDriver Windows用户 下载的chromedriver_win32.zip文件解压缩后，你会得到chromedriver.exe。 将这个文件放置在一个路径中，例如：C:\chromedriver\chromedriver.exe。 将这个路径加入系统的环境变量： 右键点击“此电脑”，选择“属性”。 选择“高级系统设置” → “环境变量”。 在“系统变量”区域中，找到“Path”，选择它并点击“编辑”。 点击“新建”，输入C:\chromedriver\，然后点击“确定”。 步骤 4: 测试ChromeDriver 打开终端或命令提示符，输入 chromedriver --version 如果成功安装，你应该会看到类似于 ChromeDriver 117.0.5938.62 这样的版本号信息。 步骤 5: 使用Selenium调用ChromeDriver 在Python代码中，确保你的Selenium脚本能够找到ChromeDriver。例如，如果没有将ChromeDriver添加到系统路径，可以在代码中直接提供其路径。 from selenium import webdriver from selenium.webdriver.chrome.service import Service # 指定chromedriver的路径 service = Service(executable_path='你的chromedriver所在路径') # 启动浏览器 driver = webdriver.Chrome(service=service) 代码实现 直接上代码（注释写的很清楚，我相信你们可以看明白）代码实现主要的点： 中途提示：防止无休止，每下载完20张图片后（可根据实际情况自行修改这个数值），程序会暂停，等待用户的输入。 并行下载：提高下载速度，使用多线程下载来并行处理多个图片的下载任务。每次批次处理后重新创建线程池：通过在 while 循环中每次处理完一批图片后，使用 with ThreadPoolExecutor 来创建一个新的线程池。线程池在每一批次结束后会自动关闭，下一次处理时重新创建一个新的线程池。 使用断点续传：如果网络中断或者长时间运行，可以记…

代码生成网站专属二维码
type: item
date: 2024-09-24T12:58:00+08:00
description: 最终的效果图如下： 想想怎么推广网站或者分享网站的文章呢？想想前些日子帮原同事简单生成了一批保存人员代码的二维码，想着我可以为自己的网站生成二维码用以推广啊，和先前一样使用 qrcode 库来生成二维码图片。 下面是简单生成的示例代码，使用 Python 生成二维码图片并保存为 PNG 文件。 如果尚未安装 qrcode 库，可以通过以下命令安装它： pip install qrcode[pil] 1. 简单示例 import qrcode # 定义二维码内容 data = "https://www.example.com" # 创建QRCode对象 qr = qrcode.QRCode( version=1, # 控制二维码大小，1是21x21的大小 error_correction=qrcode.constants.ERROR_CORRECT_L, # 容错率 box_size=10, # 每个二维码格子的像素大小 border=4, # 边框宽度 ) # 将数据添加到二维码中 qr.add_data(data) qr.make(fit=True) # 创建二维码图片 img = qr.make_image(fill='black', back_color='white') # 保存二维码图片 img.save("qrcode.png") 你可以根据需要修改二维码的内容、样式或保存路径。 2. 将网站logo加入到二维码正中央 使用PIL.Image 模块中的 Image.LANCZOS 作为图像缩放的过滤器 import qrcode from PIL import Image # 生成二维码 data = "https://www.example.com" # 二维码内容 qr = qrcode.QRCode( version=1, # 控制二维码大小 error_correction=qrcode.constants.ERROR_CORRECT_H, # 提高容错率 box_size=10, # 每个二维码格子的像素大小 border=4, # 边框宽度 ) qr.add_data(data) qr.make(fit=True) # 生成二维码图片 qr_img = qr.make_image(fill='black', back_color='white').convert('RGB') # 打开并调整网站logo大小 logo_path = "/content/favicon.ico" logo = Image.open(logo_path) # 根据二维码的大小调整logo的大小 qr_width, qr_height = qr_img.size logo_size = int(qr_width * 0.2) # logo的大小为二维码的20% logo = logo.resize((logo_size, logo_size), Image.LANCZOS) # 使用 LANCZOS 替代 ANTIALIAS # 计算logo放置在二维码中央的位置 logo_pos = ((qr_width - logo_size) // 2, (qr_height - logo_size) // 2) # 将logo粘贴到二维码上 qr_img.paste(logo, logo_pos, mask=logo) # 保存二维码图片 qr_img.save("qrcode_with_logo.png") # 显示生成的二维码 qr_img.show() 3. 以Logo为背景图生成二维码 logo图颜色太过鲜艳显眼，可以同时降低它的透明度并添加一个半透明的蒙版来增强二维码的可读性。下面是结合了调节背景图透明度和添加半透明蒙版的代码： import qrcode from PIL import Image, ImageEnhance # 生成二维码 data = "https://www.example.com" # 二维码内容 qr = qrcode.QRCode( version=1, # 控制二维码大小 error_correction=qrcode.constants.ERROR_CORRECT_H, # 提高容错率 box_size=20, # 每个二维码格子的像素大小，以适应背景图 border=0, # 去除二维码边框 ) qr.add_data(data) qr.make(fit=True) # 生成二维码图片，并转换为 RGBA 模式，支持透明背景 qr_img = qr.make_image(fill='black', back_color='white').convert('RGBA') # 打开logo图片…

小鱼特效以及回到顶部
type: item
date: 2024-09-14T06:00:00+08:00
description: 小鱼特效与回到顶部功能 效果可参考本网站 你可以将这段代码分开放在你的css、js和html（或者php）文件中，最直接方便的方式是一股脑放在你底部页面的html（或者php）文件中, fish.js文件参考网页底部小鱼游动特效 <?php if (!defined("__TYPECHO_ROOT_DIR__")) { exit(); } ?> 备案号 <?php $this->footer(); ?> 顶部 排版后的代码 <?php if (!defined("__TYPECHO_ROOT_DIR__")) { exit(); } ?> 备案号 Top <?php $this->footer(); ?> 继续 <?php if (!defined("__TYPECHO_ROOT_DIR__")) { exit(); } ?> xxx Top <?php $this->footer(); ?>

[研究学习日记] 当 Segment Anything 大模型遇上医学 X 光：从零样本到动态提示工程的探索
type: item
date: 2024-09-05T12:48:00+08:00
description: 在先前的硕士课程 Advanced Deep Learning 中，我们的课程作业带来了一个极其硬核且紧跟前沿的课题—探索 Meta AI 提出的颠覆性视觉基础大模型：Segment Anything Model (SAM) 。 SAM 在计算机视觉领域的地位，就如同 GPT 在自然语言处理领域的地位一样。它通过海量数据（1100 万张图片，超 11 亿个掩码的 SA-1B 数据集）的洗礼，实现了强大的 Zero-shot（零样本）泛化能力，并引入了优雅的 Promptable Segmentation（可提示分割） 范式。 然而，SAM 原论文主要在自然场景数据集上进行训练和评估。作为一名严谨的学习者，我产生了一个巨大的疑问：当号称能“分割一切”的 SAM，面对它极少见过的、对比度低且缺乏自然特征的医学 X 光（X-ray）图像时，它还能保持神奇的魔力吗？ 这篇博客既是我的课程学习日记，也是一次技术复盘。我将带大家从阅读 SAM 论文开始，体验 Web 端的交互分割，到使用 Python 探索 Prompt Engineering，最后自己动手搭建 YOLOv8 动态提示（Dynamic Prompting）+ SAM 的全自动流水线，并与传统的 U-Net 进行一场“终极对决”。 代码链接：Segmenting Lung X-ray Images with the Segment Anything Model 1. 理论碰撞：SAM 能胜任医疗 X 光分割吗？ 在动手敲代码之前，作业的第一步要求我们基于原论文《Segment Anything》评估 SAM 在医疗 X-ray 肺部提取任务上的预期表现。我的理论分析如下： 挑战在于领域差异（Domain Gap）： 医学 X 光图像与自然图像存在巨大鸿沟。X 光片是灰度图，对比度低，且包含许多需要专业医学先验知识才能辨别的细微解剖结构。SAM 作为通用模型，没有经过大规模医疗数据的专门微调，在处理复杂的器官边界时可能会“水土不服”。 潜力在于极强的泛化（Generalizability）： SAM 的核心卖点是其强大的零样本适应能力。得益于在海量数据上学习到的底层边缘、形状和连通区域特征，只要我们能给出精准的提示（Prompt，如明确的点或框），它极大可能具备克服领域差异的能力。 初步结论： 我预期 SAM 能给出一个相当不错的 Baseline，但极度依赖于高质量的提示（Prompt）。 2. 浅尝辄止：Web Demo 上的交互式分割初体验 俗话说实践出真知，我首先在 SAM 官方 Demo 网站 上上传了几张验证集的肺部 X 光片，分别体验了三种不同的 Prompt 方式： 点提示（Point Prompting）： 提供了极高的控制力。可以通过不断添加绿点（前景）和红点（背景）来引导模型，精细修正边界。缺点是费时费力，如果初始点选得偏，生成的初始掩码会很不理想。 边界框提示（Bounding Box Prompting）： 体验极佳！针对肺部这种大型解剖结构，画一个大致的框，SAM 瞬间就能利用全局上下文（Context）捕捉到器官边界，初始分割效果往往比单点好得多且速度更快。 全自动模式（Automatic Mode）： 全自动生成，但在 X 光片上简直是“灾难现场”。由于缺乏明确的医学语义目标，它把肺部、心脏、肋骨、背景仪器切成了无数个毫无意义的细碎小块，产生严重的过分割。 图 1：SAM的三种不同提示（Prompt）方式分割效果对比 这也印证了我的猜想：SAM 在医学图像上是有效的，但必须有人工或算法的精确引导。 3. 代码实战：Python 里的静态 Prompt Engineering 体验完 Demo，真正的硬核挑战开始了。我们在 Jupyter Notebook 中使用 Python API 来调用 SAM 处理验证集。 策略 A：启发式点提示 (Point Prompt) 我为单侧肺部精心设计了固定的坐标提示点组合：4个前景点（如 [75, 100], [80, 75], [180, 75], [185, 100]）加上 1个背景点（位于纵隔区域 [135, 150] 以防溢出）。 优化 Trick：Mask 级联预测 为了获得最佳结果，我利用了 SAM 输出多候选掩码的特性：首先让模型初步预测，提取置信度（Score）最高的那个 Mask，然后 将其作为下一次预测的输入先验（Input Mask） 进行细化打磨。 验证集结果：Mean F1-Score = 0.9084，Std = 0.0247 对于一个未经任何医疗数据微调的 Zero-shot 模型，仅靠 5 个固定坐标点就能在肺部提取上达到 90% 以上的 F1 分数，不仅精度高而且表现极其稳…

MyBatis中实现多层嵌套映射
type: item
date: 2024-08-16T10:01:00+08:00
description: 开场 书接上回，为了实现更复杂的需求，如多层嵌套映射，我们可以通过在 MyBatis 中嵌套多个 resultMap 来实现。例如，假设我们现在有三个表，它们之间存在多层嵌套关系：Category（类别）、Product（产品）和 Review（评论）。一个 Category 有多个 Product，每个 Product 又有多个 Review，这样就形成了多层嵌套的结构。 示例场景 假设有以下三个表： category 表： CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) ); product 表： CREATE TABLE product ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), price DECIMAL(10, 2), category_id INT, FOREIGN KEY (category_id) REFERENCES category(id) ); review 表： CREATE TABLE review ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(255), rating INT, product_id INT, FOREIGN KEY (product_id) REFERENCES product(id) ); 1. 实体类设计 Category 实体类 package com.example.entity; import lombok.Data; import java.util.List; @Data public class Category { private Integer id; private String name; private List<Product> products; // 一对多关系，产品列表 } Product 实体类 package com.example.entity; import lombok.Data; import java.util.List; @Data public class Product { private Integer id; private String name; private Double price; private Integer categoryId; private List<Review> reviews; // 一对多关系，评论列表 } Review 实体类 package com.example.entity; import lombok.Data; @Data public class Review { private Integer id; private String content; private Integer rating; private Integer productId; } 2. Mapper 接口设计 CategoryMapper.java package com.example.mapper; import com.example.entity.Category; import org.apache.ibatis.annotations.Select; import java.util.List; public interface CategoryMapper { // 查询所有类别，包括其产品和产品的评论信息（多层嵌套） @Select("SELECT * FROM category") List<Category> findAllCategoriesWithProductsAndReviews(); } 3. MyBatis 配置文件 我们需要在 CategoryMapper.xml 中定义嵌套的 resultMap 来处理多层嵌套的关系。 CategoryMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <mapper namespace="com.example.mapper.CategoryMapper"> <resultMap id="CategoryProductReviewMap" type="com.example.entity.Category"> <id column="category_id" property="id"/> <result column="category_name" property="name"/> <collection property="products" ofT…

MyBatis中实现一对多映射
type: item
date: 2024-08-05T09:22:00+08:00
description: 在 MyBatis 中实现一对多映射时，可以通过 resultMap 配置来实现。假设我们有两个表：Category 和 Product，一个 Category 可以有多个 Product，即这是一个一对多的关系。下面是一个具体的示例，展示如何使用 MyBatis 实现一对多映射。 示例场景 假设有以下两个表： category 表： CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) ); product 表： CREATE TABLE product ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), price DECIMAL(10, 2), category_id INT, FOREIGN KEY (category_id) REFERENCES category(id) ); 1. 创建实体类 Category 实体类 package com.example.entity; import lombok.Data; import java.util.List; @Data public class Category { private Integer id; private String name; private List<Product> products; // 一对多关系，产品列表 } Product 实体类 package com.example.entity; import lombok.Data; @Data public class Product { private Integer id; private String name; private Double price; private Integer categoryId; } 2. 创建 Mapper 接口 CategoryMapper.java package com.example.mapper; import com.example.entity.Category; import org.apache.ibatis.annotations.Select; import java.util.List; public interface CategoryMapper { // 通过 category id 查询所有产品的类别信息（包括产品信息） @Select("SELECT * FROM category") List<Category> findAllCategoriesWithProducts(); } 3. 配置一对多的 resultMap 在 CategoryMapper.xml 中定义 resultMap 来实现一对多映射。 CategoryMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <mapper namespace="com.example.mapper.CategoryMapper"> <resultMap id="CategoryProductMap" type="com.example.entity.Category"> <id column="id" property="id" /> <result column="name" property="name" /> <collection property="products" ofType="com.example.entity.Product"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="price" property="price" /> <result column="category_id" property="categoryId" /> </collection> </resultMap> SELECT c.id AS category_id, c.name AS category_name, p.id AS product_id, p.name AS product_name, p.price AS product_price, p.category_id AS product_category_id FROM category c LEFT JOIN product p ON c.id = p.category_id; </mapper> 4. Service 层与 Controller 实现 Cat…

企微bot定时推送教程
type: item
date: 2024-08-02T07:09:00+08:00
description: 一、机器人设置 设置流程：如何设置群机器人 -帮助中心-企业微信 (qq.com) 记得将Webhook复制保存下来 二、机器人定时推送功能代码实现 推送消息模块代码 clock.py #!/usr/bin/python3 # -*- coding: utf-8 -*- import requests import json import pandas as pd import os # 企业微信机器人 Webhook webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的机器人KEY' # 发送文本消息 def send_text_message(content): headers = {'Content-Type': 'application/json'} data = { "msgtype": "text", "text": { "content": content } } response = requests.post(webhook_url, headers=headers, data=json.dumps(data)) return response.json() # 发送文件 def send_file_message(file_path): # 上传文件接口，需要先把文件上传，获取media_id upload_url = f'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=你的机器人KEY&type=file' with open(file_path, 'rb') as f: files = {'file': f} response = requests.post(upload_url, files=files) result = response.json() if result.get('media_id'): # 使用media_id发送文件消息 media_id = result['media_id'] data = { "msgtype": "file", "file": { "media_id": media_id } } headers = {'Content-Type': 'application/json'} send_response = requests.post(webhook_url, headers=headers, data=json.dumps(data)) return send_response.json() else: print("文件上传失败:", result) return result # 读取并处理 Excel 文件（假设文件名为 '白云指标.xlsx'） def process_excel_file(file_path): df = pd.read_excel(file_path) # 你可以在这里进行数据处理，例如读取特定数据 summary = df.describe() # 简单获取文件的统计信息 return summary def main(): file_path = '白云指标.xlsx' if os.path.exists(file_path): # 处理 Excel 文件 summary = process_excel_file(file_path) # 发送 Excel 文件 send_file_message(file_path) # 发送文本消息，附上文件的摘要信息 send_text_message(f"已发送文件: {file_path}\n文件摘要:\n{summary}") else: send_text_message(f"文件 {file_path} 不存在") if __name__ == "__main__": main() #!/usr/bin/python3 --python包所在路径，这里使用应用镜像是CentOs8.x，环境自带python3 --如果是python以下版本，请改成以下 #!/usr/bin/python 定时设置代码 使用crontab表达式实现 * * * * * python3 /文件路径 #* * * * * crontab表达式 #如果你的环境是python3以下版本，请把python3改成python #/文件路径 需要执行的py文件路径 #示例： 0 16 * * * python3 /root/clock.py #上述代码表示在每天下午四点整运行执行/root目录下的clock.py文件以此实现定时推送功能 cronta…

分页实现示例
type: item
date: 2024-07-12T06:30:00+08:00
description: 在此例中，我们将采用 MyBatis-Plus进行快速开发，利用其内置的分页功能来实现前后端联动的分页展示。该实现包括项目初始化、后端代码编写以及前端页面的交互。 1 初始化此项目 新建项目勾选你项目所需的依赖库 在pom.xml中注入依赖：构造器所需依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.2</version> </depdency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> MyBatis-Plus可以自动生成基础的 CRUD 代码，并提供了内置的分页功能，简化了分页查询的实现。 2 后端代码模块 2.1 代码自动生成 通过MyBatis-Plus提供的代码生成器来快速生成基础的 Controller、Service、Mapper 等模块，使用GenerateTest类来实现： package com.dust; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; public class GenerateTest { public static void main(String[] args) { //创建generator对象 AutoGenerator autoGenerator = new AutoGenerator(); //数据源 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setDbType(DbType.MYSQL); dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver"); dataSourceConfig.setUsername("root"); dataSourceConfig.setPassword("102233"); dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mbtest"); autoGenerator.setDataSource(dataSourceConfig); //全局配置 GlobalConfig globalConfig = new GlobalConfig(); globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); globalConfig.setAuthor("admin"); globalConfig.setOpen(false); globalConfig.setServiceName("%sService"); autoGenerator.setGlobalConfig(globalConfig); //包信息 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.dust"); packageConfig.setEntity("entity");; packageConfig.setMapper("mapper"); packageConfig.setService("service"); packageConfig.setServiceImpl("ser…