SQL优化与性能——C++与SQL性能优化
在开发高效的数据库应用程序时,性能优化至关重要,尤其是当系统规模逐渐扩大或并发请求增加时。数据库操作往往是应用程序性能的瓶颈所在,因此,在 C++ 应用程序中合理优化数据库操作,管理数据库连接池、使用批量插入与更新等技术,能够显著提高系统的响应速度和吞吐量。本章将详细讨论以下几个方面的内容:
- 在C++中管理数据库连接池
- 使用批量插入与更新提高性能
- 避免SQL注入与安全性问题
1. 在 C++ 中管理数据库连接池
1.1 数据库连接池的必要性
数据库连接的开销较大,特别是在高并发系统中,每个请求如果都要创建新的数据库连接,将极大增加系统的负载,并影响性能。数据库连接池通过预先创建一定数量的数据库连接并复用这些连接,显著提高了数据库操作的效率,减少了因频繁创建和销毁连接而产生的资源浪费。
连接池的基本原理是在应用程序启动时创建多个连接,然后将这些连接放入一个池中。当应用程序需要进行数据库操作时,直接从连接池中借用一个连接,操作完成后再将连接归还池中。这样,避免了每次操作时都需要创建和销毁连接的开销。
1.2 在 C++ 中实现连接池
在 C++ 中管理数据库连接池,通常可以通过第三方库(如 MySQL Connector/C++)或手动实现一个简单的连接池。以下是一个简单的 C++ 数据库连接池实现:
#include <iostream>
#include <vector>
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/statement.h>
#include <cppconn/resultset.h>class DBConnectionPool {
private:std::vector<sql::Connection*> pool;sql::mysql::MySQL_Driver *driver;std::string url, user, password, dbname;size_t max_connections;public:DBConnectionPool(std::string url, std::string user, std::string password, std::string dbname, size_t max_connections): url(url), user(user), password(password), dbname(dbname), max_connections(max_connections) {driver = sql::mysql::get_mysql_driver_instance();// Initialize connection poolfor (size_t i = 0; i < max_connections; ++i) {pool.push_back(createConnection());}}~DBConnectionPool() {for (auto& conn : pool) {delete conn;}}sql::Connection* getConnection() {if (pool.empty()) {return createConnection(); // If pool is empty, create a new connection} else {sql::Connection* conn = pool.back();pool.pop_back();return conn;}}void releaseConnection(sql::Connection* conn) {pool.push_back(conn); // Return connection to pool}private:sql::Connection* createConnection() {sql::Connection* conn = driver->connect(url, user, password);conn->setSchema(dbname);return conn;}
};
1.3 连接池的优化策略
- 连接复用:避免每次数据库操作都新建连接,使用连接池中的连接进行复用,显著减少连接创建的开销。
- 连接池大小的优化:连接池的大小要根据系统的并发请求量进行调整。过小会导致频繁的连接创建,过大则会浪费内存和处理能力。
- 连接超时机制:对于长期未使用的连接,可以设置超时,自动关闭这些连接以避免资源浪费。
2. 使用批量插入与更新提高性能
2.1 批量插入与更新的意义
批量插入与更新(Bulk Insert/Update)是数据库性能优化的重要手段之一。与单条插入相比,批量插入可以显著降低网络和数据库的操作次数,减少事务的开销,提升性能。在高并发的系统中,批量操作能够有效减少数据库的负载,避免频繁的 I/O 操作。
2.1.1 批量插入的基本原理
在传统的插入操作中,每次执行 INSERT
语句时,数据库都需要进行解析、执行和提交,造成较大的性能损耗。批量插入通过将多个 INSERT
操作合并为一条 SQL 语句,在一次执行中完成多条数据的插入,大幅度减少了数据库交互的次数。
// 批量插入示例
std::string query = "INSERT INTO employees (id, name, age) VALUES (?, ?, ?)";
sql::PreparedStatement* pstmt = conn->prepareStatement(query);for (int i = 0; i < 1000; ++i) {pstmt->setInt(1, i);pstmt->setString(2, "Employee_" + std::to_string(i));pstmt->setInt(3, 30 + (i % 10));pstmt->addBatch(); // 将此插入操作添加到批处理中
}pstmt->executeBatch(); // 执行批量插入
2.1.2 批量更新的基本原理
类似于批量插入,批量更新可以通过将多个 UPDATE
语句合并在一起,在一次执行中进行多个记录的更新操作。这样做可以减少网络往返,减少数据库的处理开销。
// 批量更新示例
std::string query = "UPDATE employees SET age = ? WHERE id = ?";
sql::PreparedStatement* pstmt = conn->prepareStatement(query);for (int i = 0; i < 1000; ++i) {pstmt->setInt(1, 35); // 更新为35岁pstmt->setInt(2, i);pstmt->addBatch(); // 将此更新操作添加到批处理中
}pstmt->executeBatch(); // 执行批量更新
2.2 批量操作优化技巧
- 批量大小的控制:虽然批量操作能够提高性能,但每次批量的大小也不能过大。过大的批量操作会增加内存消耗,甚至可能引发数据库服务器的资源问题。通常建议批量大小在 500 到 1000 之间进行调整。
- 事务控制:批量操作应该在事务中执行,这样可以保证要么全部成功,要么全部回滚,确保数据一致性。
conn->setAutoCommit(false); // 关闭自动提交
for (int i = 0; i < batch_size; ++i) {pstmt->addBatch();
}
pstmt->executeBatch();
conn->commit(); // 提交事务
3. 避免 SQL 注入与安全性问题
3.1 SQL 注入概述
SQL 注入(SQL Injection)是通过构造恶意的 SQL 语句,利用应用程序中的 SQL 执行漏洞,执行不应该执行的操作(如非法查询、删除、修改数据等)。SQL 注入是 Web 应用程序中常见的安全漏洞之一,严重时可能导致数据泄露、篡改,甚至完全控制数据库。
3.2 如何防止 SQL 注入
-
使用预编译语句(Prepared Statements): 预编译语句可以有效避免 SQL 注入攻击,因为它将 SQL 语句的结构与用户输入的数据分开处理,确保数据不会被当作 SQL 代码执行。
std::string query = "SELECT * FROM users WHERE username = ? AND password = ?"; sql::PreparedStatement* pstmt = conn->prepareStatement(query); pstmt->setString(1, username); pstmt->setString(2, password); sql::ResultSet* res = pstmt->executeQuery();
-
使用参数化查询: 通过将用户输入的数据作为参数传递给 SQL 查询,而不是直接拼接到 SQL 语句中,避免了恶意 SQL 代码的注入。
std::string query = "INSERT INTO products (name, price) VALUES (?, ?)"; sql::PreparedStatement* pstmt = conn->prepareStatement(query); pstmt->setString(1, product_name); pstmt->setDouble(2, product_price); pstmt->executeUpdate();
-
对用户输入进行验证和过滤: 对用户输入的数据进行严格的验证和过滤,限制输入的字符类型、长度,防止特殊字符被插入到 SQL 语句中。
-
避免动态拼接 SQL 语句: 动态拼接 SQL 查询是 SQL 注入攻击的主要来源之一。务必避免通过字符串拼接将用户输入的数据嵌入到 SQL 语句中。
-
最小化权限原则: 数据库的权限设置要遵循最小化权限原则,确保应用程序使用的数据库账户只能执行必要的查询,避免具有删除、修改表结构等危险操作的权限。
总结
C++ 与 SQL 的性能优化是高效开发数据库应用程序的重要组成部分。从连接池管理、批量插入与更新,到 SQL 注入防护,每个环节的优化都能显著提高应用程序的执行效率,增强系统的稳定性和安全性。随着系统规模的扩大和数据量的增大,合理的数据库优化和 C++ 与数据库的高效交互将成为开发者面临的重要挑战。因此,深入理解并掌握这些技术,对于构建高性能、可靠的数据库应用程序至关重要。
相关文章:
SQL优化与性能——C++与SQL性能优化
在开发高效的数据库应用程序时,性能优化至关重要,尤其是当系统规模逐渐扩大或并发请求增加时。数据库操作往往是应用程序性能的瓶颈所在,因此,在 C 应用程序中合理优化数据库操作,管理数据库连接池、使用批量插入与更新…...
AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。
大家好,我是微学AI,今天给大家介绍一下AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。本文利用专家模…...
vscode远程连接ssh
一. 使用vscode里的ssh查件连不上远程的解决方法 删除Windows上的known_host文件,该文件会在连接之后自动生成,用于验证远程服务器的身份。 konwn_host和id_rsa,id_rsa.pub的关系 (1)konwn_host用于客户端验证远程服务…...
学习ASP.NET Core的身份认证(基于Session的身份认证2)
基于Session的身份认证通过后,后续访问控制器的函数时该如何控制访问权限?虽然可以按上篇文章方式在需要做控制的函数开头检查Session的用户标识,可以写个全局通用检查类供所需函数调用,但还是有更简便的方法,本文学习…...
深度学习基本单元结构与输入输出维度解析
深度学习基本单元结构与输入输出维度解析 在深度学习领域,模型的设计和结构是理解其性能和应用的关键。本文将介绍深度学习中的基本单元结构,包括卷积神经网络(CNN)、反卷积(转置卷积)、循环神经网络&…...
playwright 学习复仇记-1 开端
前言 说到 web 自动化,大家最熟悉的就是 selenium 了,selenium 之后又出现了三个强势的框架Puppeteer、CyPress、TestCafe, 但这3个都需要掌握 JavaScript 语言,所以只是少部分人在用。 2020年微软开源一个 UI 自动化测试工具 Pl…...
从零开始使用GOT-OCR2.0——多模态OCR项目:微调数据集构建 + 训练(解决训练报错,成功实验微调训练)
在上一篇文章记录了GOT-OCR项目的环境配置和基于官方模型参数的基础使用。环境安装的博文快速链接: 从零开始使用GOT-OCR2.0——多模态通用型OCR(非常具有潜力的开源OCR项目):项目环境安装配置 测试使用-CSDN博客 本章在环境配置…...
Rust学习笔记_10——守卫
Rust学习笔记_07——枚举和范围 Rust学习笔记_08——String Rust学习笔记_09——模式匹配 守卫 文章目录 守卫1. 介绍2. 基本用法3. 示例4. 复杂用法5. if let5.1 基本用法5.2 示例5.3 守卫与if let的区别与联系 1. 介绍 在Rust中,守卫(guardÿ…...
UE5 打包报错 Unknown structure 的解决方法
在虚幻引擎5.5 打包报错如下: UATHelper: 打包 (Windows): LogInit: Display: LogProperty: Error: FStructProperty::Serialize Loading: Property ‘StructProperty /Game/Components/HitReactionComponent/Blueprints/BI_ReactionInterface.BI_ReactionInterface…...
如何打开链接中的网址
文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了包管理相关的内容,本章回中将介绍如何使用url_launcher包.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍url_launcher包主要用来打开Url中的内容,Url可以是电话号码,网址,邮箱等内容。如…...
React 前端框架4
六、React 中的事件处理 (一)绑定事件的方式 在 React 中,事件绑定和传统的 HTML 中的事件绑定有一些不同,它采用了驼峰命名法来命名事件名称,并且事件绑定的属性值是一个函数。例如,在 HTML 中绑定点击事…...
Neo4j启动时指定JDK版本
项目使用jdk1.8,同时需要安装neo4j5.15版本,使用jdk17. 1.mac或者liunx,找到neo4j目录bin的下neo4j文件 设置JAVA_HOME: 2.windows,找到bin下面的neo4j.bat文件 set "JAVA_HOME{JDK文件目录}" 重启后生效。...
【k8s深入理解之 Scheme 补充-2】理解 register.go 暴露的 AddToScheme 函数
AddToScheme 函数 AddToScheme 就是为了对外暴露,方便别人调用,将当前Group组的信息注册到其 Scheme 中,以便了解该 Group 组的数据结构,用于后续处理 项目版本用途使用场景k8s.io/apiV1注册资源某一外部版本数据结构࿰…...
TextBlob:简单高效的自然语言处理工具
TextBlob:简单高效的自然语言处理工具 TextBlob 是一个基于 NLTK 和 Pattern 的自然语言处理库,以简单易用著称。它提供了直观的 API,支持文本分析、情感分析、拼写纠正等常见任务,非常适合快速原型开发和学习。 为什么选择 Text…...
QT:将QTableWidget内容写入txt文件中
文章详请:最近在做手在眼上的标定,首先要采集机械臂数据和图像数据,我使用tablewidget进行机械臂数据的显示,最后的计算需要将机械臂位姿数据存储在txt文件中。 引用:Qt如何保存tableWidget数据?_qt table…...
每日十题八股-2024年12月2日
1.你知道有哪个框架用到NIO了吗? 2.有一个学生类,想按照分数排序,再按学号排序,应该怎么做? 3.Native方法解释一下 4.数组与集合区别,用过哪些? 5.说说Java中的集合? 6.Java中的线程…...
R语言森林生态系统结构、功能与稳定性分析与可视化实践高级应用
在生态学研究中,森林生态系统的结构、功能与稳定性是核心研究内容之一。这些方面不仅关系到森林动态变化和物种多样性,还直接影响森林提供的生态服务功能及其应对环境变化的能力。森林生态系统的结构主要包括物种组成、树种多样性、树木的空间分布与密度…...
RDMA驱动学习(三)- cq的创建
用户通过ibv_create_cq接口创建完成队列,函数原型和常见用法如下,本节以该用法为例看下cq的创建过程。 struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe,void *cq_context,struct ibv_comp_channel *channel,int comp_vector); cq …...
Python-使用类和实例-Sun-Mon
9.2.1 Car类 class Car():"""概述车辆信息"""def __init__(self,make,model,year):"""初始化参数"""self.makemakeself.modelmodelself.yearyear //__init__方法会把依据Car类创建的实例传入的实参的值ÿ…...
【MIT-OS6.S081笔记0.5】xv6 gdb调试环境搭建
补充一下xv6 gdb调试环境的搭建,我这里装的是最新的15.2的gdb的版本。我下载的是下面的第二个xz后缀的文件: 配置最详细的步骤可以参考下面的文章: [MIT 6.S081] Lab 0: 实验配置, 调试及测试 这里记录一下踩过的一些报错: 文…...
vmware虚拟机移植
最近发现虚拟机的系统非常适合移植,接下来看一下具体的过程 复制vmdk 第一个重要的文件是保存vmdk,如果磁盘使用的是多个文件则最好进行合并一下(用着用着会发现vmdk文件特别大,这是正常的,不要想着能压缩了…...
最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,4] 输出ÿ…...
活着就好20241202
亲爱的朋友们,大家早上好!今天是2024年12月2日,第49周的第一天,也是十二月的第二天,农历甲辰[龙]年十月三十。在这个全新月份的开始、阳光初升的清晨,愿第一缕阳光悄悄探进你的房间,带给你满满的…...
Scala的练习题(成绩计算)
//1.迭代器,跳过第一个元素 //2.把字符串转成数字 //3.如何判断一个正整数是否可以被三整除? (123) % 3 0 import wyyyy.Studentimport scala.collection.mutable.ListBuffer import scala.io.Sourcecase class Student(name: St…...
Docker中配置Mysql主从备份
Mysql配置主从备份 一、Docker中实现跨服务器主从备份二、配置步骤1.配置主库2.配置从库3.遇到问题3.其它使用到的命令 一、Docker中实现跨服务器主从备份 在 Docker 中配置 MySQL 主从备份主要通过 MySQL 主从复制实现 二、配置步骤 1.配置主库 # 进入mysql主库容器 docke…...
分布式通用计算——MapReduce(重点在shuffle 阶段)
图片均来源于B站:哈喽鹏程 面向批处理的分布式计算框架——MapReduce 1、Mapreduce 起源2、适用场景3、MapReduce 词频统计原理 1、Mapreduce 起源 2、适用场景 3、MapReduce 词频统计原理 map 阶段到reduce阶段,通过hash取模来实现reduce 。比如&…...
VMware三种网络模式(桥接、NAT模式、仅主机)模式说明
VMware三种网络模式(桥接、NAT模式、仅主机)模式说明 VMware 提供了三种主要的网络连接模式:桥接模式(Bridged Mode)、NAT模式(Network Address Translation Mode)和仅主机模式(Hos…...
实习冲刺第三十八天
236.二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大࿰…...
[Linux] 信号(singal)详解(一)
标题:[Linux] 信号(singal)详解 水墨不写bug (图片来源于网络) 目录 一、认识信号 1、认识信号 2、信号特点 3、基本概念 二、信号的产生(5种方式) 三、信号的保存 正文开始: 一、认识信号 1、认识信…...
【设计模式系列】备忘录模式(十九)
目录 一、什么是备忘录模式 二、备忘录模式的角色 三、备忘录模式的典型应用场景 四、备忘录模式在Calendar中的应用 一、什么是备忘录模式 备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不暴露对象内部状态的情况下保存和恢…...
书生大模型实战营第4期——3.3 LMDeploy 量化部署实践
文章目录 1 基础任务2 配置LMDeploy环境2.1 环境搭建2.2 模型配置2.3 LMDeploy验证启动模型文件 3 LMDeploy与InternLM2.53.1 LMDeploy API部署InternLM2.53.1.1 启动API服务器3.1.2 以命令行形式连接API服务器3.1.3 以Gradio网页形式连接API服务器 3.2 LMDeploy Lite3.2.1 设置…...
11.28深度学习_bp算法
七、BP算法 多层神经网络的学习能力比单层网络强得多。想要训练多层网络,需要更强大的学习算法。误差反向传播算法(Back Propagation)是其中最杰出的代表,它是目前最成功的神经网络学习算法。现实任务使用神经网络时,…...
U盘文件夹变打不开的文件:深度解析、恢复策略与预防之道
一、U盘文件夹变打不开的文件现象解析 在日常使用U盘的过程中,我们时常会遇到这样的困扰:原本存储有序、可以轻松访问的文件夹,突然之间变成了无法打开的文件。这些文件通常以未知图标或乱码形式显示,双击或右键尝试打开时&#…...
软件工程中的需求分析流程详解
一、需求分析的定义 需求分析(Requirements Analysis)是指在软件开发过程中,通过与用户、相关人员的沟通与讨论,全面理解和确定软件需求的过程。需求分析的最终目标是清晰、准确地定义软件系统应具备的功能、性能、用户界面、约束…...
springboot369高校教师教研信息填报系统(论文+源码)_kaic
毕 业 设 计(论 文) 题目:高校教师教研信息填报系统的设计与实现 摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,…...
Docker Buildx 与 CNB 多平台构建实践
一、Docker Buildx 功能介绍 docker buildx 是 Docker 提供的一个增强版构建工具,支持更强大的构建功能,特别是在构建多平台镜像和高效处理复杂 Docker 镜像方面。 1.1 主要功能 多平台构建支持 使用 docker buildx,可以在单台设备上构建…...
VBA字典与数组第二十一讲:文本转换为数组函数Split
《VBA数组与字典方案》教程(10144533)是我推出的第三套教程,目前已经是第二版修订了。这套教程定位于中级,字典是VBA的精华,我要求学员必学。7.1.3.9教程和手册掌握后,可以解决大多数工作中遇到的实际问题。…...
开源项目 - 人脸关键点检测 facial landmark 人脸关键点 (98个关键点)
开源项目 - 人脸关键点检测 facial landmark 人脸关键点 (98个关键点) 示例: 助力快速掌握数据集的信息和使用方式。 数据可以如此美好!...
【Postgres_Python】使用python脚本批量导出PG数据库
示例代码说明: 有多个数据库需要导出为.sql格式,数据库名与sql文件名一致,读取的数据库名需要根据文件名进行拼接 import psycopg2 import subprocess import os folder_path D:/HQ/chongqing_20241112 # 获取文件夹下所有文件和文件夹的名称 filename…...
嵌入式Linux(SOC带GPU树莓派)无窗口系统下搭建 OpenGL ES + Qt 开发环境,并绘制旋转金字塔
树莓派无窗口系统下搭建 OpenGL ES Qt 开发环境,并绘制旋转金字塔 1. 安装 OpenGL ES 开发环境 运行以下命令安装所需的 OpenGL ES 开发工具和库: sudo apt install cmake mesa-utils libegl1-mesa-dev libgles2-mesa-dev libdrm-dev libgbm-dev2. 安…...
MySQL事物
目录 何谓事物? 何谓数据库事务? 并发事务带来了哪些问题? 脏读(Dirty read) 丢失修改(Lostto modify) 不可重复读(Unrepeatable read) 幻读(Phantom read) 不可重复读和幻读有什么区别? 并发事务的控制方式有哪些? SQL 标准定义了哪些事务隔离级别?…...
在 CentOS 上安装 Docker:构建容器化环境全攻略
一、引言 在当今的软件开发与运维领域,Docker 无疑是一颗璀璨的明星。它以轻量级虚拟化的卓越特性,为应用程序的打包、分发和管理开辟了崭新的高效便捷之路。无论是开发环境的快速搭建,还是生产环境的稳定部署,Docker 都展现出了…...
基于Spring Boot的宠物咖啡馆平台的设计与实现
私信我获取源码和万字论文,制作不易,感谢点赞支持。 基于Spring Boot的宠物咖啡馆平台的设计与实现 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了基于Spring Boot的宠物咖啡馆平台的设…...
JAVAWeb之javascript学习
1.js引入方式 1. 内嵌式:在head中,通过一对script标签引入JS代码;cript代码放置位置有一定的随意性,一般放在head标签中;2.引入外部js文件 在head中,通过一对script标签引入外部JS代码;注意&…...
电脑与优傲协作机器人(实体)的TCP通讯(操作记录)
目录 一、UR通信端口 二、电脑(客户端)连接协作机器人(服务端) 1.设置网络方法 2.检查设置 3.示教器切换远程控制(注) 4.客户端与协作机器人建立连接 5.连接测试 三、电脑(服务端&#…...
C++初阶——动态内存管理
目录 1、C/C内存区域划分 2、C动态内存管理:malloc/calloc/realloc/free 3、C动态内存管理:new/delete 3.1 new/delete内置类型 3.2 new/delete自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 5.1 内置类型 5.2 自定…...
Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo)
Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo) 目录 Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo) 一、简单介绍 二、PyTorch 三、CNN 1、神经网络 2、卷…...
Attention显存统计与分析
Attention显存估计 简单的Attention函数 import torch import torch.nn as nn import einops class Attention(nn.Module):def __init__(self, dim, num_heads8, qkv_biasFalse, qk_scaleNone, attn_drop0., proj_drop0.):super().__init__()self.num_heads num_headshead_d…...
java反射
反射 Java 反射是 Java 提供的一种强大特性,它允许程序在运行时动态地获取类的信息,并操作类的属性和方法。这为编写灵活、可扩展的 Java 应用程序提供了强有力的支持 获取Class对象 package ref;public class Person {private String name ;private …...
Spring Boot入门
1、Spring Boot是什么 Spring Boot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:Spring Boot底层是Spring) 大多数 Spring Boot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术 特性: 快速…...