当前位置: 首页 > news >正文

学生信息管理系统(Python+PySimpleGUI+MySQL)

吐槽一下 

        经过一段时间学习pymysql的经历,我深刻的体会到了pymysql的不靠谱之处;

        就是在使用int型传参,我写的sql语句中格式化%d了之后,我在要传入的数据传递的每一步的去强制转换了,但是他还是会报错,说我的传入参数是string,他要int,我真笑了,最后把%d换成%s结果可以了,,,然后经过我查资料才了解到pymysql他这个库会去自动匹配类型,那也就是说在使用过程中可以对数据类型的关注可以降低一点,让库来给我解决数据类型不匹配的问题

        好了,吐槽就完了,然后就是现在的代码以及内容展示了

可视化展示

登录

在这里会去获取mysql中数据库db1的表user中的数据,然后会进行判断,成立下一步,不成立,会弹出弹窗,进行警告,成立就进入菜单

然后点击左上角的”点击进行操作吧“下面的按钮是假的哈哈哈哈哈哈哈哈哈。

编辑操作

 

这里删除之后需要关闭系统,可能是因为我这里有缓存的原因

查询操作

在这里去查询所有信息就会返回如图弹窗

按学号查询

按姓名查询

按性别查询

按年龄查询

 按专业查询

别问我为什么不在这里去做个选择菜单,那就和性别一样了,懒得再进行加工了

按照班级查询

 

 代码

main文件

from GUI import GUIif __name__ == '__main__':gui = GUI()gui.get_in()

GUI文件

import PySimpleGUI as sg
from LoginDatabase import LoginDatabase
from Editor import Editor
from Find import Findsg.theme('BlueMono')class GUI(object):def __init__(self):self.db_login_conn = LoginDatabase()self.db_login = self.db_login_conn.login_database_connect_gui()self.find = Find()self.editor = Editor()def get_in(self):layout = [[sg.Image(r'E:\Student_Manager_MySQL\th.png')],[sg.T('账号'), sg.InputText(default_text='1', key='first')],[sg.T('密码'), sg.InputText(default_text='1', key='second')],[sg.B('登录', key='login', button_color='blue'), sg.B('重置', key='rollback', button_color='blue')]]window = sg.Window('登录框', layout, text_justification='center')while True:event, values = window.read()if event is None:breakif event == 'login':sg.popup_auto_close('进入检测中,请等待')if values['first'] == self.db_login[0] and values['second'] == self.db_login[1]:sg.popup_auto_close("账号密码正确,请做好准备,即将进入系统——3 2 1 ")self.menu()else:sg.popup_auto_close('输入账号或密码错误,你到底是谁,再错我可要报警了奥')if event == 'rollback':window['first'].update('')window['second'].update('')window.close()def menu(self):menu_def = [['点击进行操作吧', ['添加学生', '删除学生', '修改学生', '查询学生']]]layout = [[sg.Image(r'E:\Student_Manager_MySQL\th.png')],[sg.T('您好,欢迎您使用本系统,请进行操作', size=(20, 5), font=('宋体', 15))],[sg.Menu(menu_def, key='manage_student', size=(20, 20), font=(15, 20))],[sg.B('点击进入系统', size=(10, 5), button_color='blue', key='点击进入系统'),sg.B('点击退出系统', size=(10, 5), button_color='red', key='点击退出系统')]]window = sg.Window('菜单', layout=layout)while True:event, values = window.read()if event in (None, '退出'):breakif event == '添加学生':sg.popup_auto_close('你就添加吧,等一会再告诉你怎么写')self.add_student_gui()if event == '查询学生':self.find_student_gui()if event == '修改学生':self.change_student_gui()if event == '删除学生':self.delete_student_gui()if event == '点击进入系统':sg.popup_auto_close('被骗了吧,哈哈哈哈哈', button_color='red')if event == '点击退出系统':sg.popup_auto_close('这是真的退出了')breakwindow.close()# 添加学生信息def add_student_gui(self):layout = [[sg.T("姓名"), sg.In(default_text='请不要设置过长', key='-name-')],[sg.T("性别"), sg.OptionMenu(values=['男', '女'], key='-gender-')],[sg.T("年龄"), sg.In(default_text='请输入整数(必须输入内容)', key='-age-')],[sg.T("专业"), sg.OptionMenu(values=['软件工程', '物联网工程', '大数据', '网络工程'], key='-major-')],[sg.T("班级"), sg.Combo(values=['1班', '2班'], key='-classroom-')],[sg.B(button_text="添加", key='-add-'), sg.B(button_text="退出", key='-exit-')]]window = sg.Window(title='添加学生', layout=layout)while True:event, values = window.read()if event is None:breakif event == '-exit-':breakif event == '-add-':# print(int(values['-age-']))# print(type(int(values['-age-'])))(self.editor.insert_student(values['-name-'], values['-gender-'],values['-classroom-'], int(values['-age-']), values['-major-']))sg.popup_auto_close('添加成功')breakwindow.close()# 查询学生信息def find_student_gui(self):layout = [[sg.B('按照学号查询', key='find_id')],[sg.B('按照姓名查询', key='find_name')],[sg.B('按照性别查询', key='find_gender')],[sg.B('按照年龄查询', key='find_age')],[sg.B('按照专业查询', key='find_major')],[sg.B('按照班级查询', key='find_classroom')],[sg.B('查询所有信息', key='find_all')]]window = sg.Window('查询学生', layout)while True:event, values = window.read()if event is None:breakif event == 'find_id':layout_id = [[sg.T('请输入要查询的学生学号id'), sg.In('', key='id')],[sg.B('确认', key='id_ok')]]window_id = sg.Window('查询学生id', layout_id)while True:event_id, values_id = window_id.read()if event_id is None:breakif event_id == 'id_ok':sg.popup(self.find.find_id(int(values_id['id'])))window_id.close()if event == 'find_name':layout_name = [[sg.T('请输入要查询的学生姓名name'), sg.In('', key='name')],[sg.B('确认', key='name_ok')]]window_name = sg.Window('查询学生姓名name', layout_name)while True:event_name, values_name = window_name.read()if event_name is None:breakif event_name == 'name_ok':print(values_name['name'])sg.popup(self.find.find_name(values_name['name']))window_name.close()if event == 'find_gender':layout_gender = [[sg.T('请输入要查询的学生性别gender'), sg.In('', key='gender')],[sg.B('确认', key='gender_ok')]]window_gender = sg.Window('查询学生性别gender', layout_gender)while True:event_gender, values_gender = window_gender.read()if event_gender is None:breakif event_gender == 'gender_ok':print(values_gender['gender'])sg.popup(self.find.find_gender(str(values_gender['gender'])))window_gender.close()if event == 'find_age':layout_age = [[sg.T('请输入要查询的学生年龄age'), sg.In('', key='age')],[sg.B('确认', key='age_ok')]]window_age = sg.Window('查询学生年龄age', layout_age)while True:event_age, values_age = window_age.read()if event_age is None:breakif event_age == 'age_ok':print(values_age['age'])sg.popup(self.find.find_age(int(values_age['age'])))window_age.close()if event == 'find_major':layout_major = [[sg.T('请输入要查询的学生专业major'), sg.In('', key='major')],[sg.B('确认', key='major_ok')]]window_major = sg.Window('查询学生专业major', layout_major)while True:event_major, values_major = window_major.read()if event_major is None:breakif event_major == 'major_ok':print(values_major['major'])sg.popup(self.find.find_major(str(values_major['major'])))window_major.close()if event == 'find_classroom':layout_classroom = [[sg.T('请输入要查询的学生班级classroom'), sg.In('', key='classroom')],[sg.B('确认', key='classroom_ok')]]window_classroom = sg.Window('查询学生班级classroom', layout_classroom)while True:event_classroom, values_classroom = window_classroom.read()if event_classroom is None:breakif event_classroom == 'classroom_ok':sg.popup(self.find.find_classroom(str(values_classroom['classroom'])))window_classroom.close()if event == 'find_all':result = self.find.get_all_students()sg.Popup(result)window.close()# 删除学生def delete_student_gui(self):layout = [[sg.T('请输入要删除的学生的学号'), sg.In('', key='id')],[sg.B('确认'), sg.B('取消')]]window = sg.Window('删除学生', layout)while True:event, values = window.read()if event is None:breakif event == '确认':self.editor.delete_student(int(values['id']))sg.popup_auto_close('删除成功')breakif event == '取消':breakwindow.close()# 修改学生信息def change_student_gui(self):layout = [[sg.T('请输入要修改的学生的学号'), sg.In(key='change_id')],[sg.B('确认'), sg.B('取消')]]window = sg.Window('修改学生', layout)while True:event, values = window.read()if event is None:breakif event == '确认':self.find.find_id(values['change_id'])name = self.find.find_id(int(values['change_id']))[0]gender = self.find.find_id(values['change_id'])[1]classroom = self.find.find_id(values['change_id'])[2]age = self.find.find_id(values['change_id'])[3]major = self.find.find_id(values['change_id'])[4]layout_change = [[sg.T('姓名'), sg.In(default_text=name, key='change_name')],[sg.T('性别'), sg.In(default_text=gender, key='change_gender')],[sg.T('班级'), sg.In(default_text=classroom, key='change_classroom')],[sg.T('年龄'), sg.In(default_text=age, key='change_age')],[sg.T('专业'), sg.In(default_text=major, key='change_major')],[sg.B('修改', key='change_ok')]]window_change = sg.Window(title='修改框', layout=layout_change)while True:event_change, values_change = window_change.read()if event_change is None:breakif event_change == 'change_ok':self.editor.update_student(student_id=values['change_id'], name=values_change['change_name'],gender=values_change['change_gender'],classroom=values_change['change_classroom'],age=values_change['change_age'], major=values_change['change_major'])sg.popup_auto_close('更新成功')breakwindow_change.close()if event == '取消':breakwindow.close()

DatabaseConnect文件

import pymysql
import jsonclass DatabaseConnect(object):def __init__(self):# 选择json文件进行存储必需数据with open(r'E:\Student_Manager_MySQL\database_login.json', 'r') as f:db_config = json.load(f)self.host = db_config['host']self.port = db_config['port']self.username = db_config['username']self.password = db_config['password']self.database = db_config['database']self.charset = db_config['charset']def connect_database(self):try:db = pymysql.connect(host=self.host,port=self.port,user=self.username,password=self.password,database=self.database,charset=self.charset)# print('数据库连接成功')# 返回dbreturn dbexcept pymysql.Error as e:print('数据库连接失败' + str(e))

LoginDatabase文件

from DatabaseConnect import DatabaseConnectclass LoginDatabase(object):def __init__(self):# 创建database_connect()类的对象self.db_connect = DatabaseConnect()# 给self.db赋值为dbself.db = self.db_connect.connect_database()def login_database_connect_gui(self):# 创建游标对象cur = self.db.cursor()# 写sql语句sqlquery = 'select * from user'# 执行SQL语句cur.execute(sqlquery)# 获取SQL语句的返回值results = list(cur.fetchall())# print(results)result = []for i in results:for j in i:result.append(j)# print(result)return result# print(results)
#
#
# db_connect = database_login()
# db_connect.login_database_connect_gui()

Editor文件

from LoginDatabase import LoginDatabaseclass Editor(LoginDatabase):def __init__(self):super().__init__()# 添加学生def insert_student(self, name, gender, classroom, age, major):# try:cur = self.db.cursor()values = (name, int(age), major, gender, classroom)sql = "INSERT INTO students (name, age, major, gender, classroom) VALUES (%s, %s, %s, %s, %s)"cur.execute(sql, values)self.db.commit()# xiube = '你回去检查一下你输入的年龄'# except Exception as e:# return xiube# 修改学生def update_student(self, student_id, name, age, classroom, gender, major):cur = self.db.cursor()sql = "UPDATE students SET name = %s, gender = %s, age = %s, major = %s, classroom = %s WHERE id = %s"values = (name, gender, age, major, classroom, student_id)cur.execute(sql, values)self.db.commit()# 删除学生def delete_student(self, student_id):cur = self.db.cursor()sql = "DELETE FROM students WHERE id = %s"cur.execute(sql, (student_id,))self.db.commit()

Find文件

from LoginDatabase import LoginDatabase# 查询信息
class Find(LoginDatabase):def __init__(self):super().__init__()# 访问所有学生def get_all_students(self):cur = self.db.cursor()cur.execute("SELECT * FROM students")results = list(cur.fetchall())print(results)return results# 访问iddef find_id(self, student_id):cur = self.db.cursor()sql = 'select name,gender,classroom,age,major from students where id=%s ' % student_idcur.execute(sql)list_1 = []result = list(cur.fetchall())for i in result:for j in i:list_1.append(j)return list_1# 访问姓名def find_name(self, name):cur = self.db.cursor()sql = 'select * from students where name like %s'cur.execute(sql, (f'%{name}%',))result = cur.fetchall()return result# 访问性别def find_gender(self, gender):cur = self.db.cursor()sql = 'select * from students where gender=%s'cur.execute(sql, gender)result = cur.fetchall()return result# 访问班级def find_classroom(self, classroom):cur = self.db.cursor()sql = 'select * from students where classroom like %s'cur.execute(sql, (f"%{classroom}%",))result = cur.fetchall()return result# 访问年龄def find_age(self, age):cur = self.db.cursor()sql = 'select * from students where age=%d' % agecur.execute(sql)result = cur.fetchall()return result# 访问专业def find_major(self, major):cur = self.db.cursor()sql = 'select * from students where major=%s'cur.execute(sql, major)result = cur.fetchall()return result

json文件

{"host": "localhost","port": 3306,"username": "root","password": "1234","database": "db1","charset": "utf8mb4"
}
# 如果要用json那就要把用户名username改成你的用户名,密码和数据库相应也要改成你的

 关于可视化中图片

可视化界面中的图片是从网络找的,当然末尾也是找的;

结尾

        好了,就到这里了,这一个版本的系统需求基本实现了,缺少一个用户类,然后细分管理员以及普通用户,但是系统功能都实现了,没关系,版本迭代是迟早的,如果有需要可以私信我要源码,如果之后版本迭代的系统我也写出来了,那当然可以给你了。

        如有高见,请指教,如若有所收获,还是感激不尽。

灰太狼的大表哥-CSDN博客感谢灰太郎的大表哥给予我的一些关于pymysql的指导。

相关文章:

学生信息管理系统(Python+PySimpleGUI+MySQL)

吐槽一下 经过一段时间学习pymysql的经历,我深刻的体会到了pymysql的不靠谱之处; 就是在使用int型传参,我写的sql语句中格式化%d了之后,我在要传入的数据传递的每一步的去强制转换了,但是他还是会报错,说我…...

Java8.0标准之重要特性及用法实例(十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列…...

Linux系统中,`buffer`和`cache` 区别

在Linux系统中,buffer和cache都是操作系统用来提高磁盘I/O性能的机制,它们通过将数据暂存于内存中来减少对磁盘的直接访问。尽管它们的目的相似,但它们在实现和用途上有所不同。 Buffer 定义:buffer主要用于存储即将被写入磁盘的…...

python创建进度条的两个手搓方法

# 使用\b 回删进行手搓 import sys,time for i in range(1, 101):# 这里的10代表你的进度: 一个汉字2字节print(你的进度:,str(i)\b*(i10),flushTrue,end)time.sleep(0.5) # 利用\r手搓 import sys,time for i in range(1, 101):# \r光标回到开头print("\r", end&qu…...

JAVA—面向对象编程基础

面向对象是java编程的套路。更符合人类思维习惯,编程更直观。面向对象有三大特征:封装,继承,多态。 目录 1.理解面向对象 2.对象在计算机中的执行原理 3.类和对象的一些注意事项 4.类与对象的一些语法知识 (1&am…...

【计算机视觉学习之CV2图像操作实战:车道识别1】

车道识别 步骤 区域感兴趣高斯模糊图片灰度化边缘提取膨胀腐蚀中值滤波霍夫圆环检测直线绘制车道 import cv2 import numpy as npdef create_roi_mask(frame):height, width frame.shape[:2]# 三角形的顶点top_vertex [int(width / 2 30), int(height * 0.5 30)]bottom_l…...

动态之美:Laravel动态路由参数的实现艺术

动态之美:Laravel动态路由参数的实现艺术 在Web开发中,路由是应用程序的神经系统,它负责将请求映射到相应的处理逻辑。Laravel框架提供了一种强大而灵活的路由系统,允许开发者定义动态路由参数,从而创建更具动态性和可…...

Python练手小项目

计算器 创建一个简单的计算器,能够进行加、减、乘、除四种基本运算。 # 定义加法函数 def add(x, y):return x y# 定义减法函数 def subtract(x, y):return x - y# 定义乘法函数 def multiply(x, y):return x * y# 定义除法函数 def divide(x, y):if y 0:return…...

苹果手机通讯录恢复教程?3招速成指南

随着科技的不断进步,手机丢失、系统崩溃等意外情况也时有发生,一旦这些情况发生,我们宝贵的通讯录资料很可能会付诸东流。对此,本文为广大苹果手机用户提供一份简洁明了的通讯录恢复教程,让你轻松掌握苹果手机通讯录恢…...

python爬虫入门(五)之Re解析

一、什么是Re解析 “Re解析”是指使用正则表达式(regular expression,简称regex)进行文本解析或匹配的过程。 解析网页内容的三种方式: 1、bs4解析(最简单) 2、re解析(解析速度最快&#xf…...

可靠的图纸加密软件,七款图纸加密软件推荐

大家好啊,我是小固,今天跟大家聊聊图纸加密软件。 作为一名设计师,我深知保护自己的知识产权有多重要。曾经就因为图纸泄露,差点血本无归,那个教训可真是惨痛啊!所以我今天就给大家推荐几款靠谱的图纸加密软件,希望能帮到你们。 固信软件https://www.gooxion.com/ 首先要隆重…...

【每日一题】【最短路】【BFS】小红走矩阵 “葡萄城杯”牛客周赛 Round 53 F题 C++

“葡萄城杯”牛客周赛 Round 53 F题 小红走矩阵 题目背景 “葡萄城杯”牛客周赛 Round 53 题目描述 n m n\times m nm的矩阵由障碍和空地组成,初始时小红位于起点 ( 1 , 1 ) (1,1) (1,1),她想要前往终点 ( n , m ) (n,m) (n,m)。小红每一步可以往上…...

无线磁吸充电宝哪个牌子值得入手?什么牌子磁吸充电宝性价比高?

在当下科技日新月异的时期,无线磁吸充电宝成为了众多电子设备用户的得力助手。然而,面对市场上众多品牌和型号的无线磁吸充电宝,消费者常常陷入选择的困境:到底哪个牌子值得入手?什么牌子的磁吸充电宝性价比高&#xf…...

互联网摸鱼日报(2024-08-01)

互联网摸鱼日报(2024-08-01) 36氪新闻 氪星晚报 | Uber与比亚迪合作,将在平台上增加10万辆电动汽车;维维股份将收购大窑汽水?公司回应:消息不实;我国科学家取得全固态锂电池研究新突破 《死侍与金刚狼》,…...

Alpla003经典的价量背离的因子在可转债列表里的因子分析(附python代码)

原创文章第605篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 遗传算法给出的因子五花八门,可解释性不高。 强化学习原理不同,但结果类似。 大模型之前咱们尝试过,Quantlab3.9代码:内置大模型LL…...

进阶理解——typeof 、instanceof

typeof 、instance of 先聊聊JavaScript基本类型数据类型5种含值数据类型2种不含值类型 6种类型的*对象* typeofinstanceof总结进一步扩展一下具体讨论一下typeof局限性扩展判断方法 很多时候,回头望,理解会更深刻,也希望能帮助一些初学的同学…...

不同类型的生物反应器在支架成熟过程中具有哪些特点和应用?

3D Bioprinting of Human Tissues: Biofabrication, Bioinks, and Bioreactors是发表于《International Journal of Molecular Sciences》的一篇综述,详细介绍了3D生物打印人体组织的相关技术进展,包括数据处理、生物打印技术、生物墨水配方、生物反应器…...

8. Spring Ai之入门到精通(超级详细)

简介 2024年5月30号Spring AI 的 1.0.0 里程碑 1 版本发布。表明版本已正在巩固,并且大部分主要错误和问题已经解决,API基本已确定,不会发生很大的变化。 在与大模型集成方面,继LangChain4j之后,又一重大的框架诞生。标…...

寄存器和硬件的关系

寄存器也是一种存储器,只不过普通的存储器只能写和读。里面的数据并没有赋予什么实际意义。但是寄存器就不一样了,寄存器的每一位数据,都对应了硬件电路的状态。寄存器和外设的硬件电路,是可以进行互动的。所以,程序到…...

【WEB】ctfshow-萌新-web9-15

文章目录 题目介绍&#xff1a;题目分析&#xff1a;payload&#xff1a; 题目介绍&#xff1a; ctfshow-萌新计划-web9-15 <?php # flag in config.php include("config.php"); if(isset($_GET[c])){$c $_GET[c];if(preg_match("/system|exec|highlight…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...