基于Python、tkinter、sqlite3 和matplotlib的校園書店管理系統

????????寫一個小例子練習一下python語言。一個基于Python的校園書店管理系統,使用了tkinter庫構建圖形用戶界面(GUI),sqlite3?進行數據庫管理,matplotlib用于統計分析可視化。系統支持用戶登錄、書籍管理、客戶管理、員工管理、采購管理、銷售管理、統計分析和系統設置等功能。

一、運行環境

該系統是一個使用Python和Tkinter構建的校園書店管理系統,運行該程序需要以下環境:

(一)Python版本

使用Python 3.x版本,建議使用最新版,當前使用的是3.12版,python官網:www.python.org。因為我們在代碼中要使用到Python 3的語法和標準庫特性。例如,代碼中需要使用os.path.join等Python 3支持的路徑處理方式。

(二)第三方庫

程序中使用了一些第三方庫,需要提前安裝:

1.tkinter

這是Python的標準GUI庫,用于創建圖形用戶界面。在大多數Python 3安裝中,tkinter?已經默認包含,無需額外安裝。

2.sqlite3

這是Python的標準數據庫接口,用于操作SQLite數據庫,同樣無需額外安裝。但是數據庫管理工具SQLite-Web需要安裝。

SQLite-Web是一個基于Web瀏覽器的輕量級SQLite數據庫管理工具。它基于Python開發,免費開源,無需復雜的安裝或配置,適合快速搭建本地或內網的SQLite管理和開發環境。SQLite-Web支持常見的SQLite數據庫管理和開發任務,包括:

  1. 管理和操作已有的SQLite數據庫,或者新建數據庫;
  2. 支持表、字段以及索引的創建、修改和刪除;
  3. 支持導入/導出CSV、JSON格式的數據文件;
  4. 支持數據的增刪改查操作;
  5. 支持書簽功能,保存常用腳本;
  6. 支持URL分享查詢語句;
  7. 提供常見SQL語句幫助。

SQLite-Web的安裝非常簡單,但是它的依賴項很多,如果是不先安裝依賴項,則SQLite-Web無法安裝成功,以下是安裝依賴項的命令如下:

pip install Flask Peewee Pygments

Python環境中使用pip進行SQLite-Web安裝的命令如下:

pip install sqlite-web

建好數據庫之后,就可以執行以下命令運行SQLite-Web,來管理數據庫了:

sqlite_web /path/to/database.db

這里最好指定絕對路徑。如:

sqlite_web C:/Users/lzm07/Desktop/BookstoreApp/bookstore.db

運行成功后在瀏覽器中輸入以下地址進行訪問:http://127.0.0.1:8080/

會在頁面顯示數據表的結構(Structure),包括字段、索引、觸發器以及外鍵;同時可以修改表的字段和索引等信息。

3.matplotlib

用于繪制統計圖表。可以使用以下命令進行安裝:

pip install matplotlib

(四)數據庫文件

程序使用SQLite數據庫bookstore.db來存儲數據,確保該數據庫文件存在于與BookstoreApp.py相同的目錄下。如果文件不存在,程序會自動創建所需的表結構,并添加默認的管理員賬戶,賬號密碼都是admin。

(五)字體支持

程序中設置了?matplotlib?支持中文顯示,需要系統中安裝有相應的中文字體,如?SimHei(黑體)。如果系統中沒有該字體,可能會導致中文顯示異常。

(六)運行步驟總結

(1)確保已經安裝了 Python 3.x 版本。

(2)使用?pip?安裝?matplotlib?庫。

(3)確保?config.ini?文件存在且格式正確(后面說明如何創建)。

(4)確保?bookstore.db?文件存在或程序可以創建該文件。

(5)CMD中運行?BookstoreApp.py?文件:

python BookstoreApp.py

通過以上步驟,你應該能夠成功運行該校園書店管理系統。

、系統整體概述

接下來詳細說明如何構建整個系統,該系統使用了tkinter庫構建圖形用戶界面(GUI),sqlite3?進行數據庫管理,matplotlib用于統計分析可視化。系統支持用戶登錄、書籍管理、客戶管理、員工管理、采購管理、銷售管理、統計分析和系統設置等功能。

(一)代碼樹形結構

整個項目的代碼樹形結構如下:

BookstoreApp/

├── config.ini

├── bookstore.db(自動創建)

└── BookstoreApp.py

其中BookstoreApp是項目根目錄。里面包含了三個文件。

(二)程序組成部分

(1)配置文件模塊:config.ini?用于存儲系統的基本設置,如系統名稱、庫存警告值、每頁記錄數等。

(2)主程序模塊:BookstoreApp.py?包含了系統的主要業務邏輯和GUI界面。

(3)數據庫管理:使用?sqlite3?進行數據庫的連接、表的創建和數據的操作。

(4)用戶界面:使用?tkinter?庫創建登錄界面、主界面、導航欄和各個管理頁面。內容都包含在BookstoreApp.py文件中。

(5)統計分析:使用?matplotlib?進行數據可視化,目前代碼中未完整實現可視化部分,但預留了相關接口。內容都包含在BookstoreApp.py文件中。

系統的主要功能包括:

  1. 用戶登錄與權限控制
  2. 書籍信息的增刪改查
  3. 客戶信息的管理
  4. 員工信息的管理
  5. 采購流程的管理
  6. 銷售流程的管理
  7. 數據統計與分析
  8. 系統設置與數據庫備份恢復

BookstoreApp.py簡要說明

1.BookstoreApp.py文件樹形結構

BookstoreApp.py

├── 導入模塊

│ ??├── tkinter 及其子模塊

│ ??├── sqlite3

│ ??├── datetime

│ ??├── os

│ ??├── matplotlib 及其子模塊

│ ??├── configparser

├── 全局配置

│ ??├── 讀取配置文件 config.ini

│ ??├── 設置 matplotlib 中文字體

├── BookstoreApp 類

│ ??├── __init__(self, root)

│ ??├── load_config(self)

│ ??├── save_config(self)

│ ??├── create_tables(self)

│ ??├── create_main_window(self)

│ ??├── create_navbar(self)

│ ??├── show_login_page(self)

│ ??│ ??└── login(self)

│ ??├── setup_navigation(self)

│ ??├── show_welcome_page(self)

│ ??├── show_book_management(self)

│ ??│ ??├── search_books(self)

│ ??│ ??├── open_add_book_dialog(self)

│ ??│ ??│ ??└── add_book(self)

│ ??│ ??├── open_edit_book_dialog(self)

│ ??│ ??│ ??└── update_book(self)

│ ??│ ??└── delete_book(self)

│ ??├── load_books(self, keyword="")

│ ??├── show_customer_management(self)

│ ??│ ??├── search_customers(self)

│ ??│ ??├── open_add_customer_dialog(self)

│ ??│ ??│ ??└── add_customer(self)

│ ??│ ??├── open_edit_customer_dialog(self)

│ ??│ ??│ ??└── update_customer(self)

│ ??│ ??└── delete_customer(self)

│ ??├── load_customers(self, keyword="")

│ ??├── show_employee_management(self)

│ ??│ ??├── search_employees(self)

│ ??│ ??├── open_add_employee_dialog(self)

│ ??│ ??│ ??└── add_employee(self)

│ ??│ ??├── open_edit_employee_dialog(self)

│ ??│ ??│ ??└── update_employee(self)

│ ??│ ??└── delete_employee(self)

│ ??├── load_employees(self, keyword="")

│ ??├── show_purchase_management(self)

│ ??├── show_sale_management(self)

│ ??├── show_statistics(self)

│ ??└── show_system_settings(self)

└── 主程序入口

????└── if __name__ == "__main__":

2.各方法主要功能說明

1)類外部分

1導入模塊

  1. 導入tkinter及其子模塊用于GUI開發
  2. 導入sqlite3用于數據庫操作
  3. 導入datetime用于日期處理
  4. 導入os用于文件路徑操作
  5. 導入matplotlib及其子模塊用于數據可視化
  6. 導入configparser用于讀取配置文件

2全局配置

  1. 讀取config.ini文件獲取系統名稱、庫存警告值等配置
  2. 設置matplotlib支持中文顯示

2)BookstoreApp類方法

1初始化與配置

  1. __init__(self, root):初始化應用程序,設置窗口屬性,連接數據庫,創建主界面
  2. load_config(self):從配置文件讀取系統設置
  3. save_config(self):將當前設置保存到配置文件
  4. create_tables(self):創建數據庫表結構(書籍、客戶、員工、采購、銷售、用戶)

2界面構建

  1. create_main_window(self):創建主窗口框架
  2. create_navbar(self):創建頂部導航欄
  3. setup_navigation(self):根據用戶角色設置導航項

3用戶認證

  1. show_login_page(self):顯示登錄頁面
  2. login(self):處理用戶登錄驗證

4主頁面與功能模塊

  1. show_welcome_page(self):顯示歡迎頁面,展示系統概覽和最近銷售記錄
  2. show_book_management(self):顯示書籍管理頁面,支持搜索、添加、編輯、刪除書籍
  3. show_customer_management(self):顯示客戶管理頁面,支持客戶信息管理
  4. show_employee_management(self):顯示員工管理頁面(管理員權限)
  5. show_purchase_management(self):顯示采購管理頁面
  6. show_sale_management(self):顯示銷售管理頁面
  7. show_statistics(self):顯示統計分析頁面
  8. show_system_settings(self):顯示系統設置頁面

5數據加載與操作

  1. load_books(self, keyword):加載書籍數據,支持關鍵詞搜索
  2. load_customers(self, keyword):加載客戶數據,支持關鍵詞搜索
  3. load_employees(self, keyword):加載員工數據,支持關鍵詞搜索

6對話框與操作

  1. open_add_book_dialog(self):打開添加書籍對話框
  2. add_book(self):執行添加書籍操作
  3. open_edit_book_dialog(self):打開編輯書籍對話框
  4. update_book(self):執行更新書籍操作
  5. delete_book(self):執行刪除書籍操作
  6. 類似的客戶和員工管理方法:open_add_customer_dialog、update_customer、delete_customer 等

3.方法功能總結

這個書店管理系統采用了典型的MVC(模型 - 視圖 - 控制器)架構:

  1. 模型層:通過sqlite3操作數據庫表
  2. 視圖層:使用tkinter創建各種GUI界面
  3. 控制層:通過類方法處理用戶交互和業務邏輯

系統實現了完整的CRUD(創建、讀取、更新、刪除)操作,支持用戶認證、多角色權限管理、數據統計和系統配置等功能。配置文件和數據庫均采用UTF-8編碼,確保中文顯示正常。

系統代碼詳細說明

config.ini文件

程序依賴于config.ini文件來讀取系統配置信息,確保該文件存在于與BookstoreApp.py相同的目錄下,并且文件內容格式正確。這個地方要求文件后綴是ini文件,文件編碼一定是utf-8編碼方式,否則系統運行出錯。

[settings]system_name = bobo校園書店管理系統stock_warning_value = 10records_per_page = 20

在代碼開發工具中創建好文件保存后,可以通過用“記事本”打開,再“另存為”的方式修改編碼方式。

(1)原理:INI文件是一種常見的配置文件格式,由多個節(section)組成,每個節包含多個鍵值對(key-value pair)。[settings]?是節的名稱,下面的system_name、stock_warning_value和records_per_page是鍵,對應的值分別是系統名稱、庫存警告值和每頁記錄數。

(2)所需依賴包:無,Python 標準庫中的?configparser?模塊可用于讀取和寫入 INI 文件。

(3)運行環境:ini是文本文件,不依賴特定運行環境。

BookstoreApp.py文件

BookstoreApp.py?包含了系統的主要業務邏輯和GUI界面,是整個程序的主模塊。

1.導入依賴包

程序需要多個依賴包,所在在程序開頭,先導入python的依賴包。

import tkinter as tkfrom tkinter import ttk, messageboximport sqlite3import datetimeimport osimport matplotlib.pyplot as pltfrom matplotlib.backends.backend_tkagg import FigureCanvasTkAggfrom tkinter import filedialogimport configparser

原理說明:導入所需的Python庫和模塊,tkinter用于創建GUI,sqlite3用于數據庫操作,datetime用于處理日期時間,os用于操作系統相關操作,matplotlib用于數據可視化,configparser用于讀取和寫入配置文件。

2.讀取配置文件

要實現全局調用保存好的系統名稱庫存預警值每頁顯示記錄數,我們可以將這些配置信息存儲在一個配置文件中,然后在代碼里全局引用這些配置。為了持久化配置信息,本系統使用了ini文件來存儲配置信息,自然在加載程序之前,就要先加載配置信息,因此,在導入依賴包之后,就開始讀取配置文件。

# 讀取配置文件,使用絕對路徑config = configparser.ConfigParser()config_file_path = os.path.join(os.path.dirname(__file__), 'config.ini')# 指定編碼為 UTF-8 讀取配置文件config.read(config_file_path, encoding='utf-8')try:# 獲取配置信息system_name = config.get('settings', 'system_name')stock_warning_value = int(config.get('settings', 'stock_warning_value'))records_per_page = int(config.get('settings', 'records_per_page'))except configparser.NoSectionError:messagebox.showerror("配置文件錯誤", "未找到 'settings' 節,請檢查配置文件。")raise

(1)原理:使用configparser?模塊讀取?config.ini文件中的配置信息。如果配置文件中缺少settings節,會彈出錯誤消息框。

(2)所需依賴包:configparser(Python標準庫)。

(3)配置文件路徑問題

  1. 程序是在當前工作目錄下讀取config.ini文件,要是當前工作目錄并非BookstoreApp所在目錄,就會找不到該文件。
  2. 使用絕對路徑讀取配置文件:借助os.path.join(os.path.dirname(__file__), 'config.ini')來獲取配置文件的絕對路徑。os.path.dirname(__file__)這個讀取的是BookstoreApp.py所在的目錄。
  3. 添加異常處理:運用try-except語句捕獲configparser.NoSectionError異常,并且彈出錯誤提示框。

通過這些修改,程序就能準確讀取配置文件,避免因路徑問題而引發的錯誤。

(4)config.ini文件中文顯示亂碼的問題

config.ini文件中文顯示亂碼通常是由于文件編碼問題導致的。在讀取和寫入配置文件時,需要指定正確的編碼格式,一般使用UTF-8編碼。

  1. 讀取配置文件:在 config.read方法中指定encoding='utf-8'來讀取配置文件。
  2. 保存配置文件:在open函數中指定encoding='utf-8'來寫入配置文件。
  3. 這也要求配置文件config.ini是UTF-8編碼的。

3.設置matplotlib支持中文顯示

由于在系統中添加了圖形可視化,而圖形中有很多中文字符,所以需要支持中文。在讀取配置文件之后添加以下代碼:

plt.rcParams["font.family"] = ["SimHei"]plt.rcParams["axes.unicode_minus"] = False???# 解決負號顯示問題

(1)原理:設置?matplotlib?的字體為黑體,解決中文顯示問題,同時解決負號顯示問題。

(2)所需依賴包:matplotlib。

4.BookstoreApp類

BookstoreApp?類是系統的核心類,__init__?方法用于初始化系統,包括創建主窗口、加載配置文件、連接數據庫、創建數據庫表和顯示登錄頁面。

class BookstoreApp:def __init__(self, root):self.root = root# 讀取配置文件self.config_file = os.path.join(os.path.dirname(__file__), 'config.ini')self.load_config()self.root.title(f"{system_name}")self.root.geometry("1024x768")self.root.minsize(800, 600)# 數據庫連接self.db_path = os.path.join(os.path.dirname(__file__), "bookstore.db")  # 構建數據庫的絕對路徑# 使用絕對路徑連接數據庫self.conn = sqlite3.connect(self.db_path)self.create_tables()# 當前用戶信息self.current_user = None# 創建主界面self.create_main_window()

所需依賴包:tkinter、sqlite3、configparser。

5.load_config方法

要實現將“系統設置”保存到config.ini并全局應用,就需要先實現對配置文件內容的加載和保存,并在程序啟動時檢查并創建配置文件。load_config方法用于加載配置,save_config方法用于保存配置。

def load_config(self):try:config = configparser.ConfigParser()# 指定編碼為 UTF-8 讀取配置文件config.read(self.config_file, encoding='utf-8')self.system_name = config.get('settings', 'system_name', fallback="bobo校園書店管理系統")self.stock_warning_value = int(config.get('settings', 'stock_warning_value', fallback=10))self.records_per_page = int(config.get('settings', 'records_per_page', fallback=20))self.root.title(self.system_name)  # 設置窗口標題except Exception as e:messagebox.showerror("配置錯誤", f"加載配置失敗: {str(e)}")# 使用默認值self.system_name = "bobo校園書店管理系統"self.stock_warning_value = 10self.records_per_page = 20

(1)代碼說明:讀取配置文件中的配置信息,如果讀取失敗,使用默認值。

(2)所需依賴包:configparser、tkinter。

需要涉及到的關鍵部分包括:

  1. 配置文件管理:添加load_config和save_config方法
  2. 系統設置保存:更新show_system_settings中的保存邏輯
  3. 系統標題:在load_config中設置窗口標題
  4. 分頁功能:在所有列表頁面使用self.records_per_page
  5. 庫存預警:在統計分析中使用self.stock_warning_value
  6. 配置文件初始化:在創建表時檢查并創建配置文件

這些修改將確保系統設置能夠正確保存到配置文件,并在整個系統中全局應用。

6.save_config方法

將當前的配置信息寫入?config.ini?文件。

def save_config(self):config = configparser.ConfigParser()config['settings'] = {'system_name': self.system_name,'stock_warning_value': self.stock_warning_value,'records_per_page': self.records_per_page}try:# 指定編碼為 UTF-8 寫入配置文件with open(self.config_file, 'w', encoding='utf-8') as f:config.write(f)messagebox.showinfo("成功", "配置已保存!")except Exception as e:messagebox.showerror("錯誤", f"保存配置失敗: {str(e)}")

7.create_tables方法

在設計之初,希望減輕用戶的開發難度,省略數據庫的設計。所以你可以直接運行這個程序來使用校園書店管理系統,首次運行會自動創建數據庫并添加默認管理員賬戶(用戶名:admin,密碼:admin)。自動創建數據庫并添加默認管理員賬戶的功能就由create_tables方法實現。

def create_tables(self):# 檢查配置文件是否存在,不存在則創建if not os.path.exists(self.config_file):self.save_config()# 創建書籍表self.conn.execute('''CREATE TABLE IF NOT EXISTS books (isbn TEXT PRIMARY KEY,title TEXT NOT NULL,author TEXT,publisher TEXT,price REAL,stock INTEGER)''')# 創建客戶表self.conn.execute('''CREATE TABLE IF NOT EXISTS customers (customer_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,contact TEXT,membership TEXT DEFAULT '普通會員',points INTEGER DEFAULT 0)''')# 創建員工表self.conn.execute('''CREATE TABLE IF NOT EXISTS employees (employee_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,position TEXT,salary REAL,hire_date TEXT)''')# 創建采購表self.conn.execute('''CREATE TABLE IF NOT EXISTS purchases (purchase_id INTEGER PRIMARY KEY AUTOINCREMENT,isbn TEXT NOT NULL,quantity INTEGER NOT NULL,price REAL NOT NULL,supplier TEXT,purchase_date TEXT,FOREIGN KEY (isbn) REFERENCES books(isbn))''')# 創建銷售表self.conn.execute('''CREATE TABLE IF NOT EXISTS sales (sale_id INTEGER PRIMARY KEY AUTOINCREMENT,isbn TEXT NOT NULL,customer_id INTEGER,quantity INTEGER NOT NULL,price REAL NOT NULL,sale_date TEXT,FOREIGN KEY (isbn) REFERENCES books(isbn),FOREIGN KEY (customer_id) REFERENCES customers(customer_id))''')# 創建用戶表(用于登錄)self.conn.execute('''CREATE TABLE IF NOT EXISTS users (username TEXT PRIMARY KEY,password TEXT NOT NULL,role TEXT NOT NULL,employee_id INTEGER,FOREIGN KEY (employee_id) REFERENCES employees(employee_id))''')# 添加默認管理員賬戶(如果不存在)cursor = self.conn.cursor()cursor.execute("SELECT COUNT(*) FROM users WHERE username = 'admin'")if cursor.fetchone()[0] == 0:self.conn.execute("INSERT INTO users (username, password, role) VALUES ('admin', 'admin', '管理員')")self.conn.commit()self.conn.commit()

(1)代碼說明:檢查配置文件是否存在,如果不存在則保存默認配置。創建數據庫中的各個表,包括書籍表、客戶表、員工表、采購表、銷售表和用戶表。如果表已經存在,則不進行創建。添加默認管理員賬戶(如果不存在)。

(2)所需依賴包:sqlite3、os。

當創建好數據庫之后,可以按前文方法瀏覽器打開SQLite-Web數據庫管理工具,可以看到如下界面:

8.create_main_window方法

create_main_window方法創建程序主窗口的方法,創建窗口之后,創建頂部導航欄和主框架,初始顯示登錄頁面。

def create_main_window(self):# 創建頂部導航欄self.create_navbar()# 創建主框架self.main_frame = ttk.Frame(self.root)self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# 初始顯示登錄頁面self.show_login_page()

所需依賴包:tkinter。

運行代碼之后的,首先調用show_login_page()方法,顯示登錄界面,效果如下:

9.create_navbar方法

在create_main_window方法中要創建頂部導航欄。

def create_navbar(self):# 頂部導航欄self.navbar = ttk.Frame(self.root, height=40)self.navbar.pack(fill=tk.X)# 品牌標識self.brand_label = ttk.Label(self.navbar, text=f"{system_name}", font=("微軟雅黑", 12, "bold"))self.brand_label.pack(side=tk.LEFT, padx=10, pady=10)# 導航按鈕(初始隱藏,登錄后顯示)self.nav_buttons = {}self.nav_frame = ttk.Frame(self.navbar)# 狀態標簽self.status_label = ttk.Label(self.navbar, text="未登錄", font=("微軟雅黑", 10))self.status_label.pack(side=tk.RIGHT, padx=10, pady=10)

創建頂部導航欄,包括品牌標識、導航按鈕(初始隱藏)和狀態標簽。

當登錄主界面之后,看到的效果如下:

10.show_login_page方法

show_login_page方法,用于顯示登錄頁面,包括用戶名和密碼輸入框、登錄按鈕。用戶輸入用戶名和密碼后,點擊登錄按鈕或按下回車鍵,系統會在數據庫中查詢用戶信息,如果匹配則登錄成功,顯示歡迎頁面并設置導航欄;否則彈出登錄失敗的消息框。

def show_login_page(self):# 清空主框架for widget in self.main_frame.winfo_children():widget.destroy()# 隱藏導航按鈕if hasattr(self, 'nav_frame'):self.nav_frame.pack_forget()# 登錄框架login_frame = ttk.LabelFrame(self.main_frame, text="用戶登錄", padding=(20, 10))login_frame.pack(fill=tk.BOTH, expand=True, padx=200, pady=100, anchor=tk.CENTER)# 用戶名username_label = ttk.Label(login_frame, text="用戶名:")username_label.pack(pady=10, anchor=tk.CENTER)username_entry = ttk.Entry(login_frame, width=30)username_entry.pack(pady=5, anchor=tk.CENTER)# 密碼password_label = ttk.Label(login_frame, text="密碼:")password_label.pack(pady=10, anchor=tk.CENTER)password_entry = ttk.Entry(login_frame, width=30, show="*")password_entry.pack(pady=5, anchor=tk.CENTER)# 登錄按鈕def login():username = username_entry.get()password = password_entry.get()cursor = self.conn.cursor()cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))user = cursor.fetchone()if user:self.current_user = {'username': user[0],'role': user[2]}self.status_label.config(text=f"當前用戶: {username} ({user[2]})")messagebox.showinfo("登錄成功", f"歡迎回來,{username}!")self.show_welcome_page()self.setup_navigation()else:messagebox.showerror("登錄失敗", "用戶名或密碼錯誤")login_button = ttk.Button(login_frame, text="登錄", command=login)login_button.pack(pady=20, anchor=tk.CENTER)# 綁定回車事件到登錄按鈕username_entry.bind("<Return>", lambda event: login())password_entry.bind("<Return>", lambda event: login())# 設置焦點username_entry.focus()

show_login_page方法方法中又嵌套了login()方法。

11.setup_navigation方法

系統劃分了兩個角色,分別是管理員普通員工根據用戶角色顯示不同的導航項管理員可以訪問所有功能,普通員工只能訪問部分功能。添加退出登錄按鈕,點擊后返回登錄頁面。

def setup_navigation(self):# 清空現有導航按鈕for widget in self.nav_frame.winfo_children():widget.destroy()# 根據用戶角色顯示不同的導航項if self.current_user['role'] == '管理員':nav_items = [("首頁", self.show_welcome_page),("書籍管理", self.show_book_management),("客戶管理", self.show_customer_management),("員工管理", self.show_employee_management),("采購管理", self.show_purchase_management),("銷售管理", self.show_sale_management),("統計分析", self.show_statistics),("系統設置", self.show_system_settings)]else:  # 普通員工nav_items = [("首頁", self.show_welcome_page),("書籍管理", self.show_book_management),("客戶管理", self.show_customer_management),("銷售管理", self.show_sale_management)]# 添加導航按鈕for text, command in nav_items:btn = ttk.Button(self.nav_frame, text=text, command=command)btn.pack(side=tk.LEFT, padx=5, pady=5)# 添加退出按鈕ttk.Button(self.nav_frame, text="退出登錄", command=self.show_login_page).pack(side=tk.RIGHT, padx=5, pady=5)# 顯示導航框架self.nav_frame.pack(side=tk.LEFT, padx=10, pady=5)

管理員的界面效果如下:

當在管理員賬號下,添加了員工之后,可以使用員工的賬號密碼登錄,登錄的界面效果如下:

兩種角色可以管理的功能是不同的。

12.show_welcome_page方法

顯示歡迎頁面,包括系統概覽(書籍總數、客戶總數、今日銷售額、庫存預警)和最近銷售記錄。從數據庫中查詢相關數據并顯示在界面上。

def show_welcome_page(self):# 清空主框架for widget in self.main_frame.winfo_children():widget.destroy()# 創建歡迎界面welcome_label = ttk.Label(self.main_frame, text=f"歡迎使用{system_name}", font=("微軟雅黑", 24))welcome_label.pack(pady=50)# 顯示系統信息info_frame = ttk.LabelFrame(self.main_frame, text="系統概覽", padding=(10, 5))info_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)# 獲取統計數據cursor = self.conn.cursor()# 書籍總數cursor.execute("SELECT COUNT(*) FROM books")book_count = cursor.fetchone()[0]# 客戶總數cursor.execute("SELECT COUNT(*) FROM customers")customer_count = cursor.fetchone()[0]# 今日銷售額today = datetime.date.today().strftime("%Y-%m-%d")cursor.execute("SELECT SUM(price * quantity) FROM sales WHERE sale_date = ?", (today,))today_sales = cursor.fetchone()[0] or 0# 庫存預警cursor.execute(f"SELECT COUNT(*) FROM books WHERE stock < {self.stock_warning_value}")low_stock_count = cursor.fetchone()[0]# 顯示統計數據stats = [("書籍總數", book_count),("客戶總數", customer_count),("今日銷售額", f"¥{today_sales:.2f}"),("庫存預警", low_stock_count)]for i, (label, value) in enumerate(stats):frame = ttk.Frame(info_frame)frame.pack(fill=tk.X, padx=10, pady=5)ttk.Label(frame, text=label, font=("微軟雅黑", 12)).pack(side=tk.LEFT, padx=10)ttk.Label(frame, text=str(value), font=("微軟雅黑", 16, "bold")).pack(side=tk.RIGHT, padx=10)# 最近銷售記錄recent_frame = ttk.LabelFrame(self.main_frame, text="最近銷售記錄", padding=(10, 5))recent_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)# 創建表格columns = ("sale_id", "isbn", "title", "customer", "quantity", "price", "date")self.recent_tree = ttk.Treeview(recent_frame, columns=columns, show="headings", height=5)# 設置列標題self.recent_tree.heading("sale_id", text="銷售ID")self.recent_tree.heading("isbn", text="ISBN")self.recent_tree.heading("title", text="書名")self.recent_tree.heading("customer", text="客戶")self.recent_tree.heading("quantity", text="數量")self.recent_tree.heading("price", text="金額")self.recent_tree.heading("date", text="日期")# 設置列寬self.recent_tree.column("sale_id", width=80)self.recent_tree.column("isbn", width=120)self.recent_tree.column("title", width=200)self.recent_tree.column("customer", width=100)self.recent_tree.column("quantity", width=80)self.recent_tree.column("price", width=80)self.recent_tree.column("date", width=120)self.recent_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)# 獲取最近10條銷售記錄cursor.execute('''SELECT s.sale_id, s.isbn, b.title, c.name, s.quantity, s.price, s.sale_dateFROM sales sLEFT JOIN books b ON s.isbn = b.isbnLEFT JOIN customers c ON s.customer_id = c.customer_idORDER BY s.sale_date DESCLIMIT 10''')for row in cursor.fetchall():self.recent_tree.insert("", tk.END, values=row)

所需依賴包:tkinter、sqlite3、datetime。

13.show_book_management方法

顯示書籍管理頁面,包括搜索框、添加書籍按鈕、書籍列表表格、編輯按鈕和刪除按鈕。用戶可以搜索書籍、添加新書籍、編輯現有書籍信息,以及操作之后對數據列表進行刷新。

def show_book_management(self):# 清空主框架for widget in self.main_frame.winfo_children():widget.destroy()# 創建管理界面manage_frame = ttk.LabelFrame(self.main_frame, text="書籍管理", padding=(10, 5))manage_frame.pack(fill=tk.BOTH, expand=True)# 上部操作區top_frame = ttk.Frame(manage_frame)top_frame.pack(fill=tk.X, padx=10, pady=10)# 搜索框ttk.Label(top_frame, text="搜索:").pack(side=tk.LEFT, padx=5)search_entry = ttk.Entry(top_frame, width=30)search_entry.pack(side=tk.LEFT, padx=5)def search_books():keyword = search_entry.get()self.load_books(keyword)ttk.Button(top_frame, text="搜索", command=search_books).pack(side=tk.LEFT, padx=5)# 添加按鈕def open_add_book_dialog():dialog = tk.Toplevel(self.root)dialog.title("添加書籍")dialog.geometry("500x400")dialog.resizable(True, True)dialog.transient(self.root)dialog.grab_set()# 表單框架form_frame = ttk.Frame(dialog, padding=(20, 10))form_frame.pack(fill=tk.BOTH, expand=True)# ISBNttk.Label(form_frame, text="ISBN:").grid(row=0, column=0, sticky=tk.W, pady=10)isbn_entry = ttk.Entry(form_frame, width=30)isbn_entry.grid(row=0, column=1, pady=10)# 書名ttk.Label(form_frame, text="書名:").grid(row=1, column=0, sticky=tk.W, pady=10)title_entry = ttk.Entry(form_frame, width=30)title_entry.grid(row=1, column=1, pady=10)# 作者ttk.Label(form_frame, text="作者:").grid(row=2, column=0, sticky=tk.W, pady=10)author_entry = ttk.Entry(form_frame, width=30)author_entry.grid(row=2, column=1, pady=10)# 出版社ttk.Label(form_frame, text="出版社:").grid(row=3, column=0, sticky=tk.W, pady=10)publisher_entry = ttk.Entry(form_frame, width=30)publisher_entry.grid(row=3, column=1, pady=10)# 價格ttk.Label(form_frame, text="價格:").grid(row=4, column=0, sticky=tk.W, pady=10)price_entry = ttk.Entry(form_frame, width=30)price_entry.grid(row=4, column=1, pady=10)# 庫存ttk.Label(form_frame, text="庫存:").grid(row=5, column=0, sticky=tk.W, pady=10)stock_entry = ttk.Entry(form_frame, width=30)stock_entry.grid(row=5, column=1, pady=10)# 添加按鈕def add_book():isbn = isbn_entry.get()title = title_entry.get()author = author_entry.get()publisher = publisher_entry.get()try:price = float(price_entry.get())stock = int(stock_entry.get())except ValueError:messagebox.showerror("錯誤", "價格和庫存必須是數字!")returnif not isbn or not title:messagebox.showerror("錯誤", "ISBN和書名不能為空!")returntry:self.conn.execute("INSERT INTO books VALUES (?, ?, ?, ?, ?, ?)",(isbn, title, author, publisher, price, stock))self.conn.commit()messagebox.showinfo("成功", "書籍添加成功!")dialog.destroy()self.load_books()except sqlite3.IntegrityError:messagebox.showerror("錯誤", "ISBN已存在!")except Exception as e:messagebox.showerror("錯誤", f"添加書籍失敗: {str(e)}")ttk.Button(form_frame, text="添加", command=add_book).grid(row=6, column=0, columnspan=2, pady=20)ttk.Button(top_frame, text="添加書籍", command=open_add_book_dialog).pack(side=tk.RIGHT, padx=5)# 表格區域table_frame = ttk.Frame(manage_frame)table_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# 創建表格columns = ("isbn", "title", "author", "publisher", "price", "stock")self.book_tree = ttk.Treeview(table_frame, columns=columns, show="headings", height=self.records_per_page)# 設置列標題self.book_tree.heading("isbn", text="ISBN")self.book_tree.heading("title", text="書名")self.book_tree.heading("author", text="作者")self.book_tree.heading("publisher", text="出版社")self.book_tree.heading("price", text="價格")self.book_tree.heading("stock", text="庫存")# 設置列寬self.book_tree.column("isbn", width=150)self.book_tree.column("title", width=200)self.book_tree.column("author", width=150)self.book_tree.column("publisher", width=150)self.book_tree.column("price", width=80, anchor=tk.E)self.book_tree.column("stock", width=80, anchor=tk.E)self.book_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)# 添加滾動條scrollbar = ttk.Scrollbar(table_frame, orient=tk.VERTICAL, command=self.book_tree.yview)self.book_tree.configure(yscroll=scrollbar.set)scrollbar.pack(side=tk.RIGHT, fill=tk.Y)# 底部按鈕區域bottom_frame = ttk.Frame(manage_frame)bottom_frame.pack(fill=tk.X, padx=10, pady=10)# 編輯按鈕def open_edit_book_dialog():selected_item = self.book_tree.selection()if not selected_item:messagebox.showinfo("提示", "請先選擇一本書!")returnitem = self.book_tree.item(selected_item[0])values = item['values']dialog = tk.Toplevel(self.root)dialog.title("編輯書籍")dialog.geometry("500x400")dialog.resizable(True, True)dialog.transient(self.root)dialog.grab_set()# 表單框架form_frame = ttk.Frame(dialog, padding=(20, 10))form_frame.pack(fill=tk.BOTH, expand=True)# ISBN (只讀)ttk.Label(form_frame, text="ISBN:").grid(row=0, column=0, sticky=tk.W, pady=10)isbn_entry = ttk.Entry(form_frame, width=30)isbn_entry.grid(row=0, column=1, pady=10)isbn_entry.insert(0, values[0])isbn_entry.configure(state='readonly')# 書名ttk.Label(form_frame, text="書名:").grid(row=1, column=0, sticky=tk.W, pady=10)title_entry = ttk.Entry(form_frame, width=30)title_entry.grid(row=1, column=1, pady=10)title_entry.insert(0, values[1])# 作者ttk.Label(form_frame, text="作者:").grid(row=2, column=0, sticky=tk.W, pady=10)author_entry = ttk.Entry(form_frame, width=30)author_entry.grid(row=2, column=1, pady=10)author_entry.insert(0, values[2])# 出版社ttk.Label(form_frame, text="出版社:").grid(row=3, column=0, sticky=tk.W, pady=10)publisher_entry = ttk.Entry(form_frame, width=30)publisher_entry.grid(row=3, column=1, pady=10)publisher_entry.insert(0, values[3])# 價格ttk.Label(form_frame, text="價格:").grid(row=4, column=0, sticky=tk.W, pady=10)price_entry = ttk.Entry(form_frame, width=30)price_entry.grid(row=4, column=1, pady=10)price_entry.insert(0, values[4])# 庫存ttk.Label(form_frame, text="庫存:").grid(row=5, column=0, sticky=tk.W, pady=10)stock_entry = ttk.Entry(form_frame, width=30)stock_entry.grid(row=5, column=1, pady=10)stock_entry.insert(0, values[5])# 更新按鈕def update_book():isbn = isbn_entry.get()title = title_entry.get()author = author_entry.get()publisher = publisher_entry.get()try:price = float(price_entry.get())stock = int(stock_entry.get())except ValueError:messagebox.showerror("錯誤", "價格和庫存必須是數字!")returnif not isbn or not title:messagebox.showerror("錯誤", "ISBN和書名不能為空!")returntry:self.conn.execute("UPDATE books SET title=?, author=?, publisher=?, price=?, stock=? WHERE isbn=?",(title, author, publisher, price, stock, isbn))self.conn.commit()messagebox.showinfo("成功", "書籍更新成功!")dialog.destroy()self.load_books()except Exception as e:messagebox.showerror("錯誤", f"更新書籍失敗: {str(e)}")ttk.Button(form_frame, text="更新", command=update_book).grid(row=6, column=0, columnspan=2, pady=20)ttk.Button(bottom_frame, text="編輯", command=open_edit_book_dialog).pack(side=tk.LEFT, padx=5)# 刪除按鈕def delete_book():selected_item = self.book_tree.selection()if not selected_item:messagebox.showinfo("提示", "請先選擇一本書!")returnitem = self.book_tree.item(selected_item[0])isbn = item['values'][0]title = item['values'][1]if messagebox.askyesno("確認", f"確定要刪除《{title}》嗎?"):try:# 先檢查是否有銷售記錄cursor = self.conn.cursor()cursor.execute("SELECT COUNT(*) FROM sales WHERE isbn = ?", (isbn,))count = cursor.fetchone()[0]if count > 0:messagebox.showerror("錯誤", "該書存在銷售記錄,不能刪除!")returnself.conn.execute("DELETE FROM books WHERE isbn = ?", (isbn,))self.conn.commit()messagebox.showinfo("成功", "書籍刪除成功!")self.load_books()except Exception as e:messagebox.showerror("錯誤", f"刪除書籍失敗: {str(e)}")ttk.Button(bottom_frame, text="刪除", command=delete_book).pack(side=tk.LEFT, padx=5)# 刷新按鈕ttk.Button(bottom_frame, text="刷新", command=lambda: self.load_books()).pack(side=tk.RIGHT, padx=5)# 加載書籍數據self.load_books()

所需依賴包:tkinter、sqlite3。

書籍管理界面的效果如下:

14.load_books方法

show_book_management方法中,需要加載書籍數據,使用load_books方法。

def load_books(self, keyword=""):# 清空表格for item in self.book_tree.get_children():self.book_tree.delete(item)cursor = self.conn.cursor()if keyword:# 搜索查詢query = """SELECT isbn, title, author, publisher, price, stock FROM books WHERE isbn LIKE ? OR title LIKE ? OR author LIKE ?"""param = f"%{keyword}%"cursor.execute(query, (param, param, param))else:# 獲取所有書籍cursor.execute("SELECT isbn, title, author, publisher, price, stock FROM books")# 填充表格for row in cursor.fetchall():self.book_tree.insert("", tk.END, values=row)

15.show_customer_management方法

顯示客戶管理頁面,支持客戶信息管理。

load_customers()方法加載客戶列表。

添加客戶信息的界面如下:

16.show_employee_management方法

顯示員工管理頁面(管理員權限)

load_employees()方法加載員工列表

添加員工信息的界面如下:

17.show_purchase_management方法

顯示采購管理頁面

load_purchases()方法加載采購記錄列表

在添加采購記錄彈窗上,get_book_info()方法獲取書籍信息。

18.show_sale_management方法

顯示銷售管理頁面

load_sales()方法加載銷售記錄列表

在添加銷售記錄彈窗上,get_book_info()方法獲取書籍信息。get_customer_info()方法獲取客戶信息。

19.show_statistics方法

顯示統計分析頁面

update_statistics()方法用于當選擇新的參數時,更新統計數據。

20.show_system_settings方法

顯示系統設置頁面,包括了常規設置、數據庫設置、備份與恢復、用戶設置。

四、系統完整代碼

可以在我的CSDN博客上下載。地址:https://download.csdn.net/download/lzm12278828/91092825?

總結

該校園書店管理系統通過配置文件和數據庫實現了基本的書店管理功能,使用GUI界面提供了良好的用戶體驗。系統的主要依賴包為?tkinter、sqlite3?和?matplotlib,運行環境為 Python 3.x。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86059.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86059.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86059.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習×第十四卷:集成學習中篇——她從每次錯誤中修正自己

&#x1f380;【開場 她終于愿意回看自己貼錯的地方了】 &#x1f98a;狐狐&#xff1a;“她貼過你很多次&#xff0c;但每次貼歪了&#xff0c;都只是低頭沉默。” &#x1f43e;貓貓&#xff1a;“現在不一樣了喵……她開始反思&#xff0c;是不是哪一刻該繞過來貼你背后&…

LeetCode 2537.統計好子數組的數目

給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回 nums 中 好 子數組的數目。 一個子數組 arr 如果有 至少 k 對下標 (i, j) 滿足 i < j 且 arr[i] arr[j] &#xff0c;那么稱它是一個 好 子數組。 子數組 是原數組中一段連續 非空 的元素序列。 示例 1&#x…

Python 開發環境管理和常用命令

包管理器選擇 從輕到重: venv → virtualenv → conda venv: Python 3.3 內置&#xff0c;輕量級虛擬環境virtualenv: 第三方包&#xff0c;支持更多Python版本conda: 科學計算友好&#xff0c;包含包管理和環境管理 Python 版本支持 查看各版本支持狀態&#xff1a;Status…

macOS - 根據序列號查看機型、保障信息

文章目錄 最近在看 MacBook 二手機&#xff0c;有個咸魚賣家放個截圖 說不清參數&#xff0c;于是想根據 序列號 查看機型。蘋果提供了這樣的網頁&#xff1a; https://checkcoverage.apple.com/ &#xff08;無需登錄&#xff09; 結果 2025-06-20&#xff08;五&#xff09;…

數字化項目調研過程中需要的文章

Hello&#xff0c;大家好 &#xff0c;我是東哥說-MES 最近寫了不少的文章&#xff0c;為了方便閱讀&#xff0c;特意重新整理了數字化相關的文章鏈接&#xff0c;也便于大家閱讀 數字工廠項目啟動與業務需求調研執行指南-CSDN博客文章瀏覽閱讀725次&#xff0c;點贊28次&…

LangChain4j之會話功能AiServices工具類的使用(系列二)

概述 LangChain4j 的會話功能 AiServices 工具類&#xff0c;可助力輕松實現智能對話。它能記錄對話上下文&#xff0c;讓 AI 回答連貫且貼合情境。使用起來&#xff0c;先引入類&#xff0c;配置好相關參數&#xff0c;如模型地址、密鑰等。接著&#xff0c;調用相應方法傳入…

Qt 中使用 gtest 做單元測試

作者&#xff1a;billy 版權聲明&#xff1a;著作權歸作者所有&#xff0c;商業轉載請聯系作者獲得授權&#xff0c;非商業轉載請注明出處 gtest 簡介 GoogleTest&#xff08;也稱為gtest&#xff09;是由 Google 開發的一個 C 單元測試框架&#xff0c;用于編寫、組織和運行…

WPF TreeView 數據綁定完全指南:MVVM 模式實現

WPF TreeView 數據綁定完全指南&#xff1a;MVVM 模式實現 一、TreeView 綁定的核心概念1.1 MVVM 模式下的 TreeView 綁定原理1.2 綁定關系示意圖 二、完整實現步驟2.1 創建節點模型類2.2 創建 ViewModel2.3 XAML 綁定配置2.4 設置 Window 的 DataContext 三、關鍵特性詳解3.1 …

坤馳科技QTS4200戰鷹(Battle Eagle)系列實時頻譜分析記錄回放系統

QTS4200戰鷹(Battle Eagle)系列 實時頻譜分析記錄回放系統 精準采集&#xff5c;高效回放&#xff5c;拓展頻譜分析新邊界 坤馳科技傾力打造新一代集實時頻譜分析、高速信號記錄與精準信號回放于一體的便攜式系統&#xff0c;為無線電監測、無線通信、國防等領域提供全面而高…

Flask(二) 路由routes

文章目錄 基本路由定義路由參數路由規則設置請求方法&#xff08;GET/POST&#xff09;路由函數返回靜態文件和模板Blueprint&#xff08;模塊化路由&#xff09;顯示當前所有路由 Flask 路由是 Web 應用程序中將 URL 映射到 Python 函數的機制。 定義路由&#xff1a;使用 app…

在el-image組件的預覽中添加打印功能(自定義功能)

思路&#xff1a;給圖片添加點擊事件&#xff0c;通過js獲取預覽的工具欄&#xff0c;在工具欄中添加自定義按鈕及事件 1、html 中 image標簽 <el-image style"width: 139px; height: 89px" :src"fileUrl" :preview-src-list"[fileUrl]" cli…

TongWeb替換tomcat

1、背景 國家近年來大力推進信息技術應用創新產業&#xff08;信創&#xff09;&#xff0c;要求關鍵領域采用自主可控的國產軟硬件。Tomcat作為國外開源產品&#xff0c;存在潛在的安全風險和技術依賴。TongWeb作為國產中間件&#xff0c;符合信創目錄要求&#xff0c;滿足政府…

聯合語音和文本機器翻譯,支持多達100種語言(nature子刊論文研讀)

簡介&#xff1a; &#x1f30d; SEAMLESSM4T 是一種單一模型&#xff0c;實現了跨越多達 101 種源語言和多種目標語言的語音到語音、語音到文本、文本到語音和文本到文本翻譯及自動語音識別。&#x1f680; 該模型性能顯著超越現有級聯系統&#xff0c;特別是在語音到文本和語…

網站公安網安備案查詢API集成指南

網站公安網安備案查詢API集成指南 引言 隨著互聯網應用的日益普及&#xff0c;網絡安全和個人隱私保護越來越受到重視。公安網安備案作為保障網絡安全的重要措施之一&#xff0c;對于確保網站合法合規運營具有重要意義。為了幫助開發者更加便捷地獲取網站的公安網安備案信息&a…

如何用遠程調試工具排查 WebView 與原生通信問題(iOS或Android)

WebView 在移動端開發中的角色越來越關鍵&#xff0c;尤其在混合架構&#xff08;Hybrid&#xff09;項目中&#xff0c;它作為前端與原生的橋梁&#xff0c;承載了大量交互行為。但這個橋梁并不總是穩固&#xff0c;尤其是在涉及 JSBridge 通信 時&#xff0c;前端調用原生接口…

使用 spark-submit 運行依賴第三方庫的 Python 文件

python文件在spark集群運行真的麻煩&#xff0c;煩冗 spark運行分為了三個模式&#xff0c;本地模式/client模式/cluster模式 文章目錄 本地模式client模式cluster模式參考 本地模式 現在的spark支持python3了&#xff0c;支持python2的版本已經很落后了&#xff0c;所以需要…

【android bluetooth 協議分析 05】【藍牙連接詳解2】【acl_interface_t介紹】

1. acl_interface_t 介紹 acl_interface_t 結構體及其子結構體&#xff0c;目的是封裝處理 Classic、LE、SCO 連接及鏈路事件的回調函數&#xff0c;用于 HCI 事件與上層藍牙協議棧的解耦分發。 system/main/shim/acl_legacy_interface.h typedef struct {void (*on_connect…

TouchDIVER Pro觸覺手套:虛擬現實中的多模態交互新選擇

隨著虛擬現實技術的發展&#xff0c;用戶對沉浸式體驗的需求不斷提升。TouchDIVER Pro觸覺手套通過力反饋、紋理渲染和溫度提示三種核心機制&#xff0c;為用戶提供更真實的觸覺感知體驗。六個驅動點分布于五指與手掌&#xff0c;結合全手追蹤與低延遲連接&#xff0c;實現精準…

想考華為HCIA-AI,應該怎么入門?

華為HCIA-AI Solution認證作為華為人工智能認證體系的起點&#xff0c;吸引了許多希望進入AI領域或提升專業技能的學習者。如果你正考慮考取這個認證&#xff0c;這份純科普向的入門指南希望能夠幫你理清學習路徑和關鍵準備點&#xff01; 第一、明確認證目標與要求 HCIA-AI S…

【Oracle篇】Windows平臺單進程多線程架構設計與實現(比對Linux多進程架構)

&#x1f4ab;《博主主頁》&#xff1a; &#x1f50e; CSDN主頁__奈斯DB &#x1f50e; IF Club社區主頁__奈斯、 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對SQLserver、N…