设计模式-命令模式详解
命令模式详解及真实场景解决方案
模式定义
命令模式是一种行为设计模式,将请求封装为独立对象,包含执行操作所需的所有信息。通过这种方式,可以实现请求的参数化、队列管理、撤销/重做等高级功能,同时解耦请求发送者与接收者。
真实场景案例:智能家居控制系统
需求背景:
控制多种智能设备(灯光、空调、窗帘)
支持手机APP、语音助手、物理开关多种控制方式
需要实现功能:
单设备控制
情景模式(如"影院模式":关灯+关窗帘+开空调)
操作历史记录与撤销
延迟执行(如定时关闭设备)
痛点问题:
控制方式与设备强耦合
复杂操作组合难以管理
状态回滚实现困难
异步执行需求
解决方案代码实现
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;// 命令接口
interface Command {void execute();void undo();
}// 设备基类(Receiver)
abstract class SmartDevice {protected String location;public SmartDevice(String location) {this.location = location;}public abstract String getStatus();
}// 具体设备
class Light extends SmartDevice {private boolean isOn;private int brightness = 100;public Light(String location) {super(location);}public void toggle() {isOn = !isOn;}public void setBrightness(int level) {this.brightness = Math.max(0, Math.min(100, level));}@Overridepublic String getStatus() {return String.format("%s灯光:%s 亮度:%d%%",location, isOn ? "开" : "关", brightness);}
}class AirConditioner extends SmartDevice {private boolean isOn;private int temperature = 26;public AirConditioner(String location) {super(location);}public void powerSwitch() {isOn = !isOn;}public void setTemperature(int temp) {this.temperature = temp;}@Overridepublic String getStatus() {return String.format("%s空调:%s 温度:%d℃",location, isOn ? "开" : "关", temperature);}
}// 具体命令实现
class LightToggleCommand implements Command {private final Light light;private boolean previousState;public LightToggleCommand(Light light) {this.light = light;}@Overridepublic void execute() {previousState = light.isOn;light.toggle();System.out.println(light.getStatus());}@Overridepublic void undo() {if (light.isOn != previousState) {light.toggle();}System.out.println("(撤销) " + light.getStatus());}
}class TemperatureControlCommand implements Command {private final AirConditioner ac;private final int targetTemp;private int previousTemp;public TemperatureControlCommand(AirConditioner ac, int temp) {this.ac = ac;this.targetTemp = temp;}@Overridepublic void execute() {previousTemp = ac.temperature;ac.setTemperature(targetTemp);System.out.println(ac.getStatus());}@Overridepublic void undo() {ac.setTemperature(previousTemp);System.out.println("(撤销) " + ac.getStatus());}
}// 宏命令(批量命令)
class MacroCommand implements Command {private final List<Command> commands;private final String name;public MacroCommand(String name, List<Command> commands) {this.name = name;this.commands = commands;}@Overridepublic void execute() {System.out.println("=== 执行情景模式:" + name + " ===");commands.forEach(Command::execute);}@Overridepublic void undo() {System.out.println("=== 撤销情景模式:" + name + " ===");// 反向执行撤销for (int i = commands.size()-1; i >= 0; i--) {commands.get(i).undo();}}
}// 命令管理器(Invoker)
class CommandManager {private final Deque<Command> history = new ArrayDeque<>();private final Deque<Command> redoStack = new ArrayDeque<>();public void executeCommand(Command command) {command.execute();history.push(command);redoStack.clear();}public void undo() {if (!history.isEmpty()) {Command cmd = history.pop();cmd.undo();redoStack.push(cmd);}}public void redo() {if (!redoStack.isEmpty()) {Command cmd = redoStack.pop();cmd.execute();history.push(cmd);}}public void showHistory() {System.out.println("\n操作历史:");history.forEach(cmd -> System.out.println("- " + cmd.getClass().getSimpleName()));}
}// 使用示例
public class CommandPatternExample {public static void main(String[] args) {// 初始化设备Light livingRoomLight = new Light("客厅");AirConditioner bedroomAC = new AirConditioner("卧室");// 创建命令Command lightCmd = new LightToggleCommand(livingRoomLight);Command tempCmd = new TemperatureControlCommand(bedroomAC, 24);// 创建情景模式MacroCommand cinemaMode = new MacroCommand("影院模式", List.of(new LightToggleCommand(livingRoomLight),new TemperatureControlCommand(bedroomAC, 22)));// 命令管理器CommandManager manager = new CommandManager();// 执行操作manager.executeCommand(lightCmd); // 开关灯manager.executeCommand(tempCmd); // 调节温度manager.executeCommand(cinemaMode);// 执行情景模式System.out.println("\n=== 执行撤销操作 ===");manager.undo(); // 撤销情景模式manager.undo(); // 撤销温度调节manager.showHistory();}
}
真实场景问题解决方案
解耦控制逻辑:
解决方案:将设备操作封装为独立命令对象
优势:新增控制方式无需修改设备类
情景模式实现:
关键技术:宏命令组合多个命令
扩展性:自由组合任意命令序列
撤销/重做机制:
实现方式:使用双栈结构(历史栈+重做栈)
注意事项:宏命令需反向撤销
异步执行支持:
// 异步命令执行示例
class AsyncCommand implements Runnable {private final Command command;public AsyncCommand(Command command) {this.command = command;}@Overridepublic void run() {command.execute();}
}// 使用线程池执行
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(new AsyncCommand(lightCmd));
状态持久化:
// 命令序列化示例
public void saveCommands(String filename) throws IOException {try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {oos.writeObject(new ArrayList<>(history));}
}
典型问题及应对策略
问题场景 | 解决方案 | 实现要点 |
---|---|---|
需要不同精度的撤销 | 使用备忘录模式保存完整状态 | 在命令中保存设备快照 |
命令执行可能失败 | 添加事务补偿机制 | 实现rollback()方法 |
需要权限控制 | 在命令执行前进行权限校验 | 在execute()方法中添加检查逻辑 |
命令需要延迟执行 | 结合定时任务队列实现 | 使用ScheduledExecutorService |
设备状态同步问题 | 实现命令状态查询接口 | 添加getResult()方法 |
模式优化技巧
命令可视化:
// 在命令接口中添加描述方法
interface Command {String getDescription();
}// 在管理器中实现操作日志
public void showFormattedHistory() {history.forEach(cmd -> System.out.printf("[%tT] %s%n", LocalTime.now(), cmd.getDescription()));
}
智能撤销限制:
// 设置最大历史记录数
private static final int MAX_HISTORY = 50;public void executeCommand(Command command) {if (history.size() >= MAX_HISTORY) {history.removeLast();}// ...原有逻辑...
}
命令参数验证:
// 在命令执行前验证参数有效性
class TemperatureControlCommand implements Command {public void execute() {if (targetTemp < 16 || targetTemp > 30) {throw new IllegalArgumentException("温度设置超出范围");}// ...原有逻辑...}
}
命令组合优化:
// 实现并行执行的宏命令
class ParallelMacroCommand implements Command {public void execute() {ExecutorService executor = Executors.newFixedThreadPool(4);commands.forEach(cmd -> executor.submit(cmd::execute));executor.shutdown();}
}
适用场景总结
需要将操作请求者与实现者解耦
需要支持事务性操作(执行/撤销)
需要支持命令队列或日志功能
需要支持高层操作(组合命令)
需要实现不同时刻指定请求
通过命令模式可以提升系统扩展性达40%以上,特别是在需要支持复杂操作管理的IoT系统、图形编辑器、事务处理系统等领域效果显著。当需要扩展远程控制或分布式操作时,命令模式可以作为良好的基础架构。
一句话总结
命令模式通过抽象命令的统一管理,保存了每一个命令当前情况下业务的状态,保证业务能快速进行每个命令间状态的切换。(存储的撤销和回退就是这么做的)
mysql的binlog类似于命令模式,不过是通过记录命令,而不是记录当前状态的方式进行回退
相关文章:
设计模式-命令模式详解
命令模式详解及真实场景解决方案 模式定义 命令模式是一种行为设计模式,将请求封装为独立对象,包含执行操作所需的所有信息。通过这种方式,可以实现请求的参数化、队列管理、撤销/重做等高级功能,同时解耦请求发送者与接收者。 …...
基于Python(Django)+SQLite 实现(Web) 点菜管理系统
点菜管理系统 课程设计任务与要求 1、任务 题目:点菜管理信息系统 问题描述: 随着网络的迅速发展,越来越多的人开始接受甚至时依赖了网络营业的这种交易形式,传统的点菜模式不仅浪费时间,效率低下,而且…...
泰鸿万立上市:加强产品规划和前瞻性研发 打造优质汽车零部件制造商
4月9日,浙江泰鸿万立科技股份有限公司(股票简称“泰鸿万立”,股票代码“603210”)正式登陆上交所主板。 招股书显示,泰鸿万立主营业务为汽车结构件、功能件的研发、生产与销售。经过十余年发展,公司拥有了…...
Charles的安装和使用教程
Charles抓包工具与Sniff Master在Windows上的安装与使用指南 1. Charles抓包工具安装 1.1 下载Charles 进入Charles官网(https://www.charlesproxy.com/download/)下载最新版本的安装包 1.2 安装与激活 正常安装后,打开会提示试用版30天限制进入授权码生成页面…...
论文阅读笔记:Adaptive Multi-Modal Cross-Entropy Loss for Stereo Matching
论文阅读笔记:Adaptive Multi-Modal Cross-Entropy Loss for Stereo Matching 1 背景2 创新点3 方法4 模块4.1 基础和问题描述4.2 自适应多模态概率模型4.3 主模态视差估计器 5 效果6 结论 1 背景 尽管深度学习在立体匹配方面取得了巨大成功,但恢复准确…...
JavaScript学习教程,从入门到精通,JavaScript 运算符及语法知识点详解(8)
JavaScript 运算符及语法知识点详解 一、JavaScript 运算符 1. 算术运算符 用于执行数学运算: 加法- 减法* 乘法/ 除法% 取模(余数) 递增-- 递减** 幂运算(ES6) let a 10, b 3; console.log(a b); // 13 conso…...
聊聊Spring AI的ETL Pipeline
序 本文主要研究一下Spring AI的ETL Pipeline DocumentReader org/springframework/ai/document/DocumentReader.java public interface DocumentReader extends Supplier<List<Document>> {default List<Document> read() {return get();}}有TextReader…...
spark架构和RDD相关概念
运行架构: Spark采用master - slave结构,Driver作为master负责作业任务调度,Executor作为slave负责实际执行任务。 核心组件 Driver:执行Spark任务的main方法,将用户程序转化为作业,在Executor间调度任务&…...
Cloud Kernel SIG 季度动态:发布ANCK 6.6-003版本,支持一测多证
Cloud Kernel SIG(Special Interest Group):支撑龙蜥内核版本的研发、发布和服务,提供生产可用的高性价比内核产品。 01 SIG 整体进展 发布 ANCK 6.6-003 版本。 一测多证流程建立。 OOT 驱动基线更新。 海光平台适配进展更新…...
【11】数据结构之基于线性表的查找算法
目录标题 平均查找长度ASL(Average Search Length)顺序表查找法折半查找法索引顺序查找法 平均查找长度ASL(Average Search Length) 定义:为确定元素在列表中的位置,需要和给定值进行比较的关键字个数的期望值,称之为查找算法成功时的平均查…...
铼赛智能Edge mini斩获2025法国设计大奖 | 重新定义数字化齿科美学
铼赛智能(RAYSHAPE)革命性新品——椅旁3D打印机Edge mini荣获2025年法国设计奖(FRENCH DESIGN AWARDS,简称FDA)产品设计类大奖。作为全球工业设计领域最具影响力的奖项之一,这一殊荣不仅是对产品极简美学的…...
成为一种国家战略范畴的新基建的智慧园区开源了
智慧园区场景视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界…...
Codeforces Round 1016 (Div. 3)题解
题目地址 https://codeforces.com/contest/2093 锐评 在所有题意都理解正确的情况下,整体难度不算太难。但是偏偏存在F这么恶心的题意,样例都不带解释一下的,根本看不懂题。D题也恶心,在于递归过程的拆分,需要点数学…...
安全理念和安全产品发展史
从安全理念的发展历史来看,技术与产品的演进始终围绕 “威胁对抗” 与 “业务适配” 两大核心展开。以下从七个关键阶段解析安全技术与产品的发展脉络,并结合最新实践与未来趋势提供深度洞察: 一、密码学奠基阶段(1970s 前) 安全理念:以 “信息保密” 为核心,防御手段…...
【深度学习】Downstream Model:预训练模型的下游应用与微调技术
Downstream Model:预训练模型的下游应用与微调技术 文章目录 Downstream Model:预训练模型的下游应用与微调技术1 什么是Downstream Model(下游模型)2 预训练模型与下游任务的关系3 微调技术与迁移学习微调的必要性高效迁移学习参…...
每日算法-250409
这是我今天的算法学习记录。 2187. 完成旅途的最少时间 题目描述 思路 二分查找 解题过程 为什么可以使用二分查找? 问题的关键在于寻找一个最小的时间 t,使得在时间 t 内所有公交车完成的总旅途次数 sum 大于等于 totalTrips。 我们可以观察到时间的单…...
【CSS 选择器组合规则详解】
基础选择器组合 空格:后代选择器 > 直接子元素选择器 . 类选择器 : 伪类选择器 多类选择器 .class1.class2 :多类组合 .class1 .class2 :类的所有后代 .class1 > .class2 :类的子元素特殊选择器 :nth-child() :nth-of-…...
手机静态ip地址怎么获取?方法与解析
而在某些特定情境下,我们可能需要为手机设置一个静态IP地址。本文将详细介绍手机静态IP地址详解及获取方法 一、什么是静态IP地址? 静态IP:由用户手动设置的固定IP地址,不会因网络重启或设备重连而改变。 动态IP:由路…...
NumPy对二维矩阵中的每个元素进行加减乘除和对数运算
使用NumPy对二维矩阵中的每个元素进行加减乘除和对数运算的方法如下: 1. 加减乘除运算 对每个元素进行标量运算,可直接使用算术运算符。 示例代码: import numpy as nparr np.array([[1, 2], [3, 4]])# 加法 result_add arr 5 print(&…...
基于C8051F340单片机的精确定时1S的C程序
一、前言 C8051F340单片的定时器2 是一个 16 位的计数器/定时器,由两个 8 位的 SFR 组成:TMR2L(低字节)和TMR2H(高字节)。定时器 2 可以工作在 16 位自动重装载方式、8 位自动重装载方式(两个 …...
提升Windows安全的一些措施
由简单到复杂,仅供参考 一、杀毒软件: 1、杀毒能力: https://haokan.hao123.com/v?vid3883775443252827335&pdhaokan_share 2、使用注意: 一台主机只安装一个杀毒软件就可以了 杀毒软件会误报,造成正常文件…...
中科岩创基坑自动化监测解决方案
1.行业现状 城市基坑开挖具有施工风险高、施工难度大等特点。由于地下土体性质、荷载条件、施工环境的复杂性,单根据地质勘察资料和室内土工试验参数来确定设计和施工方案,往往含有许多不确定因素,对在施工过程中引发的土体性状、环境、邻近建…...
Elasticsearch 系列专题 - 第二篇:数据建模与索引管理
在掌握了 Elasticsearch 的基本概念和操作后,本篇将重点介绍如何设计和管理索引,以及如何高效地导入和维护数据。这对于构建一个高效、可扩展的搜索系统至关重要。 1. 索引设计 1.1 如何选择合适的索引结构 索引是 Elasticsearch 的核心,设计时需考虑以下因素: 数据用途:…...
解决缓存穿透的布隆过滤器与布谷鸟过滤器:谁更适合你的应用场景?
目录 一、布隆过滤器:高效的空间节省者 1.1 布隆过滤器是什么? 1.2 工作原理 1.3 优点 1.4 缺点 1.5 适用场景 二、布谷鸟过滤器:解决删除难题的创新者 2.1 布谷鸟过滤器是什么? 2.2 工作原理 2.3 优点 2.4 缺点 2.5 适用场景 三、…...
OpenHarmony子系统开发 - 调测工具(一)
OpenHarmony子系统开发 - 调测工具(一) 一、bytrace使用指导 简介 bytrace是开发人员用于追踪进程轨迹、分析性能的一种工具,主要对内核ftrace进行了封装和扩展,来支持用户态的打点。通过该工具可以打开想要查看的用户态和内核l…...
Qt中的鼠标事件
1.鼠标进入事件和鼠标离开事件 1.1添加新文件 1.2ui界面 拖出一个Label控件,修改frameShape为Box,使边框更明显 1.3代码实现 #ifndef MYLABEL_H #define MYLABEL_H#include <QLabel>class myLabel : public QLabel {Q_OBJECT public:explicit m…...
MySQL JOIN详解:INNER JOIN与LEFT JOIN的选择与应用
在数据库查询中,JOIN操作是最常用也最重要的操作之一。不同的JOIN类型会导致完全不同的查询结果,正确选择JOIN类型是编写高效、准确SQL查询的关键。本文将深入探讨INNER JOIN和LEFT JOIN的区别、应用场景以及常见问题。 一、JOIN基础概念 1. 什么是JOI…...
Flink 反压下的 TCP 流控制
1. 什么是 Flink 反压和 TCP 流控制? 反压(Backpressure)是什么? 反压是分布式流处理系统中一种自我调节机制。当下游处理数据的速度跟不上上游发送数据的速度时,反压会让上游放慢发送速度,以避免系统过载…...
山东大学软件学院项目实训开发日志(7)之测试前后端本地部署
基于队长搭建的springbootvue框架,在本地进行测试搭建。 在运行后端过程中,出现下图错误: 查找后发现这个问题出现在 Maven 项目的 pom.xml 文件中,显示找不到一些依赖项。所以在此进行最简单的重新加载项目得以解决,…...
YOLOv11训练中精准率召回率与mAP@0.5的动态变化分析
目标检测模型的训练过程涉及多个关键性能指标和损失函数的变化,这些数据能够直观反映模型的收敛速度、最终精度以及改进效果。本文旨在通过绘制YOLOv11模型在训练过程中的精准率(Precision)、召回率(Recall)、mAP0.5 、…...
Windows下ElasticSearch8.x的安装步骤
下载ElasticSearch:https://www.elastic.co/downloads/elasticsearch (我下载的是目前最新版8.17.4)解压ElasticSearch 进入到ElasticSearch的bin目录下双击elasticsearch.bat 弹出控制台并开始执行,在这一步会输出初始账号和密码…...
Leetcode hot100 (day 8,9)
爬楼梯 做法一:小斐波那契数列,只要注意记忆化递归即可 class Solution { public:int dp[50];int climbStairs(int n) {if(dp[n])return dp[n];if(n2){return dp[2]2;}if(n1){return dp[1]1;}//if(dp[n])return dp[n];return dp[n]climbStairs(n-1)clim…...
LinuxSocket套接字编程
1.介绍函数使用 1.创建套接字 int socket(int domain, int type, int protocol); domain:指定协议族,如AF_INET(IPv4)或AF_INET6(IPv6)。 type:指定套接字类型,如SOCK_DGRAM&#…...
青少年编程考试 CCF GESP Python五级认证真题 2025年3月
Python 五级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 A A A B D B A D A D C A A D B 1 单选题(每题 2 分,共 30 分) 第 1 题 链表不具备的特点是( )。 A. 可随机访问任何一个元素 B. 插入、删除操作不需要移动元素 C…...
Java-对比两组对象找出发生变化的字段工具-支持枚举映射-支持时间-支持显示对应字段中文描述-嵌套list等场景
实体字段比较器(对比两组对象找出发生变化的字段工具类开发) 支持枚举映射 支持时间 支持显示对应字段中文描述 支持嵌套list等场景 下载地址: Java-对比两组对象找出发生变化的字段工具-支持枚举映射-支持时间-支持显示对应字段中文描述-嵌…...
电影舆情分析可视化平台管理端实现
电影舆情分析可视化平台管理端实现 系统概述 本系统的用户主要有三类,游客、普通用户以及电影从业人员。 面向游客和普通用户的是电影网站,系统提供一个便捷的平台,供普通用户搜索和了解电影的基本信息,支持电影预告片播放&…...
【Linux】进程信号(下)
在上一篇中,我们详细探讨了信号的预备知识和产生方式(如硬件异常、终端输入、kill命令、系统调用等)及其背后的操作系统行为。信号作为进程间异步通信的核心机制,其生命周期远不止“产生”这一环节——信号的保存与处理才是实现可…...
华为数字芯片机考2025合集2已校正
单选 1. 题目内容 关于亚稳态的描述错误的是( )。 1. 解题步骤 1.1 理解亚稳态(Metastability)的核心特性 亚稳态是指触发器无法在指定时间内稳定输出有效逻辑电平(0或1)的状态,其关键特点…...
【大模型微调】如何解决llamaFactory微调效果与vllm部署效果不一致如何解决
以下个人没整理太全 一、生成式语言模型的对话模板介绍 使用Qwen/Qwen1.5-0.5B-Chat训练 对话模板不一样。回答的内容就会不一样。 我们可以看到例如qwen模型的tokenizer_config.json文件,就可以看到对话模板,一般同系列的模型,模板基本都…...
基于视觉语言模型的机器人实时探索系统!ClipRover:移动机器人零样本视觉语言探索和目标发现
作者:Yuxuan Zhang 1 ^{1} 1, Adnan Abdullah 2 ^{2} 2, Sanjeev J. Koppal 3 ^{3} 3, and Md Jahidul Islam 4 ^{4} 4单位: 2 , 4 ^{2,4} 2,4佛罗里达大学电气与计算机工程系RoboPI实验室, 1 , 3 ^{1,3} 1,3佛罗里达大学电气与计算机工程系F…...
Java常用工具算法-6--秘钥托管云服务AWS KMS
前言: 之前我们介绍了一些常用的加密算法(如:对称加密AES,非对称加密RSA,ECC等),不论是哪一种都需要涉及到秘钥的管理。通常的做法都是把秘钥放到配置文件中进行配置,但是对于一些高…...
Shell脚本的学习
编写脚本文件 定义以开头:#!/bin/bash #!用来声明脚本由什么shell解释,否则使用默认shel 第一步:编写脚本文件 #!/bin/bash #注释 echo "这是输出" 第二步:加上执行权限:chmod x 脚本文件名.sh 第三步&…...
Java——pdf增加水印
文章目录 前言方式一 itextpdf项目依赖引入编写PDF添加水印工具类测试效果展示 方式二 pdfbox依赖引入编写实现类效果展示 扩展1、将inputstream流信息添加水印并导出zip2、部署出现找不到指定字体文件 资料参考 前言 近期为了知识库文件导出,文件数据安全处理&…...
Redis过期key处理、内存淘汰策略与缓存一致性策略实践方案
在现代的高性能应用开发中,Redis作为一款极为热门的内存数据库,其快速的读写性能和丰富的数据结构使其在缓存、消息队列等诸多领域得到了广泛应用。然而,在实际使用过程中,处理好Redis过期key、选择合适的内存淘汰策略以及确保缓存…...
深入 C++ 线程库:从创建到同步的探索之旅
C在<thread>中定义了C线程库. 创建多线程 #include <iostream> #include <thread> using namespace std; void show(int id, int count) { //线程函数for (int i 0; i < count; i) {cout << "id:" << id << ",值:&qu…...
LangChain使用大语言模型构建强大的应用程序
LangChain简介 LangChain是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互ÿ…...
程序化广告行业(72/89):Tag Manager系统代码操作与行业发展剖析
程序化广告行业(72/89):Tag Manager系统代码操作与行业发展剖析 大家好!在技术领域不断探索的过程中,我深刻体会到知识共享的重要性。写这篇博客,就是希望能和大家一起深入了解程序化广告行业,…...
数据结构实验3.3:求解迷宫路径问题
文章目录 一,问题描述二,基本要求三,算法分析(一)整体思路(二)详细步骤1. 输入迷宫大小并生成迷宫2. 定义走步规则3. 深度优先搜索(DFS)4. 输出结果 (三&…...
基于SpringBoot的线上历史馆藏系统【附源码】
基于SpringBoot的线上历史馆藏系统(源码L文说明文档) 4 系统设计 系统在设计的过程中,必然要遵循一定的原则才可以,胡乱设计是不可取的。首先用户在使用过程中,能够直观感受到功能操作的便利性,符合…...
Mybatis的springboot项目使用
删除数据 & 占位符 一般常用占位符进行数据库操作,也就是预编译sql。 在UserMapper中定义删除接口 /** 根据id删除用户*/ Delete("delete from user where id #{id}") void deleteById(Integer id);若想要获取返回值,声明为Integer (s…...