python项目实战:图书管理系统

系统概述

这个图书管理系统是一个命令行界面的应用程序,主要功能包括图书管理、用户管理和借阅管理。系统使用SQLite作为数据库后端,通过面向对象的方式封装了各种操作。

系统设计结构

1. 数据库设计

系统设计了三个主要数据表:

  1. books表:存储图书信息

    • id: 主键,自增

    • title: 书名

    • author: 作者

    • isbn: ISBN号(唯一)

    • status: 图书状态(available/borrowed)

    • borrowed_date: 借出日期

    • due_date: 应还日期

  2. users表:存储用户信息

    • id: 主键,自增

    • name: 用户名

    • email: 邮箱(唯一)

    • password: 密码

  3. borrow_records表:存储借阅记录

    • id: 主键,自增

    • book_id: 外键关联books表

    • user_id: 外键关联users表

    • borrow_date: 借出日期

    • return_date: 归还日期

2. 类设计

系统核心是LibrarySystem类,封装了所有数据库操作:

class LibrarySystem:
    def __init__(self, db_path='library.db'):
        # 初始化数据库连接
        self.db_path = db_path
        self.conn = None
        self.cursor = None
        self.connect()
        self.create_tables()

主要方法分为几类:

  1. 数据库连接管理

    • connect(): 建立数据库连接

    • disconnect(): 关闭数据库连接

  2. 表结构管理

    • create_tables(): 创建所需的数据库表

  3. 图书管理功能

    • add_book(): 添加新书

    • remove_book(): 删除图书

    • search_books(): 搜索图书

    • list_books(): 列出所有图书

  4. 用户管理功能

    • register_user(): 注册新用户

    • authenticate_user(): 用户认证

  5. 借阅管理功能

    • borrow_book(): 借阅图书

    • return_book(): 归还图书

    • list_borrowed_books(): 列出所有借出的图书

代码实现分析

1. 数据库连接与表创建

def create_tables(self):
    """创建必要的表"""
    # 创建图书表
    self.cursor.execute('''
    CREATE TABLE IF NOT EXISTS books (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        author TEXT NOT NULL,
        isbn TEXT UNIQUE,
        status TEXT NOT NULL DEFAULT 'available',
        borrowed_date TEXT,
        due_date TEXT
    )
    ''')
  • 使用IF NOT EXISTS避免重复创建表

  • 设置了适当的约束(NOT NULL, UNIQUE等)

  • 定义了外键关系确保数据完整性

2. 图书管理实现

添加图书:

def add_book(self, title, author, isbn=None):
    try:
        self.cursor.execute(
            "INSERT INTO books (title, author, isbn) VALUES (?, ?, ?)",
            (title, author, isbn)
        )
        self.conn.commit()
        return True, "图书添加成功"
    except sqlite3.IntegrityError:
        return False, "ISBN已存在"
  • 使用参数化查询防止SQL注入

  • 捕获IntegrityError处理唯一约束冲突

  • 返回操作结果和消息

3. 借阅管理实现

借阅图书:

def borrow_book(self, book_id, user_id):
    from datetime import datetime, timedelta

    try:
        # 检查图书是否存在和可借状态
        self.cursor.execute("SELECT * FROM books WHERE id = ?", (book_id,))
        book = self.cursor.fetchone()
        if not book:
            return False, "图书不存在"
        if book[4] == 'borrowed':
            return False, "图书已被借出"

        # 更新图书状态
        borrow_date = datetime.now().strftime("%Y-%m-%d")
        due_date = (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d")
        self.cursor.execute(
            "UPDATE books SET status = 'borrowed', borrowed_date = ?, due_date = ? WHERE id = ?",
            (borrow_date, due_date, book_id)
        )

        # 记录借阅信息
        self.cursor.execute(
            "INSERT INTO borrow_records (book_id, user_id, borrow_date) VALUES (?, ?, ?)",
            (book_id, user_id, borrow_date)
        )

        self.conn.commit()
        return True, f"借阅成功,应在 {due_date} 前归还"
  • 设置14天的借阅期限

  • 同时更新图书状态和创建借阅记录

  • 使用事务确保数据一致性

 

归还图书:

def return_book(self, book_id):
    from datetime import datetime

    try:
        # 检查图书状态
        self.cursor.execute("SELECT * FROM books WHERE id = ?", (book_id,))
        book = self.cursor.fetchone()
        if not book:
            return False, "图书不存在"
        if book[4] == 'available':
            return False, "图书未被借出"

        # 更新图书状态
        return_date = datetime.now().strftime("%Y-%m-%d")
        self.cursor.execute(
            "UPDATE books SET status = 'available', borrowed_date = NULL, due_date = NULL WHERE id = ?",
            (book_id,)
        )

        # 更新借阅记录
        self.cursor.execute(
            "UPDATE borrow_records SET return_date = ? WHERE book_id = ? AND return_date IS NULL",
            (return_date, book_id)
        )

        self.conn.commit()

        # 检查逾期情况
        due_date = datetime.strptime(book[6], "%Y-%m-%d")
        if datetime.now() > due_date:
            days_overdue = (datetime.now() - due_date).days
            return True, f"归还成功,但已逾期 {days_overdue} 天"
  • 处理图书状态更新和借阅记录更新

  • 检查并计算逾期天数

  • 提供详细的反馈信息

系统特点

  1. 数据完整性:

    • 使用数据库约束(UNIQUE, NOT NULL等)

    • 外键关系确保关联数据有效性

    • 事务处理保证操作原子性

  2. 安全性:

    • 参数化查询防止SQL注入

    • 密码存储(虽然示例中为明文,实际应用中应加密)

  3. 用户体验:

    • 清晰的错误提示

    • 详细的操作反馈

    • 简单的命令行界面

  4. 可扩展性:

    • 模块化设计便于功能扩展

    • 清晰的数据库结构易于修改

优化与改进建议

  1. 密码安全:

    • 当前明文存储密码不安全,应使用哈希算法(如bcrypt)加密

  2. 日志记录:

    • 添加操作日志功能,记录重要操作

  3. 更复杂的搜索:

    • 实现多条件组合搜索

    • 添加分页功能

  4. 用户界面:

    • 可以开发图形界面或Web界面提升用户体验

  5. 数据备份:

    • 添加数据库备份功能

完整代码

import sqlite3
import os


class LibrarySystem:
    def __init__(self, db_path='library.db'):
        self.db_path = db_path
        self.conn = None
        self.cursor = None
        self.connect()
        self.create_tables()

    def connect(self):
        """连接到数据库"""
        self.conn = sqlite3.connect(self.db_path)
        self.cursor = self.conn.cursor()

    def disconnect(self):
        """断开数据库连接"""
        if self.cursor:
            self.cursor.close()
        if self.conn:
            self.conn.close()

    def create_tables(self):
        """创建必要的表"""
        # 创建图书表
        self.cursor.execute('''
        CREATE TABLE IF NOT EXISTS books (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            title TEXT NOT NULL,
            author TEXT NOT NULL,
            isbn TEXT UNIQUE,
            status TEXT NOT NULL DEFAULT 'available',
            borrowed_date TEXT,
            due_date TEXT
        )
        ''')

        # 创建用户表
        self.cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            email TEXT UNIQUE NOT NULL,
            password TEXT NOT NULL
        )
        ''')

        # 创建借阅记录表
        self.cursor.execute('''
        CREATE TABLE IF NOT EXISTS borrow_records (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            book_id INTEGER NOT NULL,
            user_id INTEGER NOT NULL,
            borrow_date TEXT NOT NULL,
            return_date TEXT,
            FOREIGN KEY (book_id) REFERENCES books (id),
            FOREIGN KEY (user_id) REFERENCES users (id)
        )
        ''')

        self.conn.commit()

    # 图书管理功能
    def add_book(self, title, author, isbn=None):
        """添加图书"""
        try:
            self.cursor.execute(
                "INSERT INTO books (title, author, isbn) VALUES (?, ?, ?)",
                (title, author, isbn)
            )
            self.conn.commit()
            return True, "图书添加成功"
        except sqlite3.IntegrityError:
            return False, "ISBN已存在"
        except Exception as e:
            return False, f"添加图书失败: {str(e)}"

    def remove_book(self, book_id):
        """删除图书"""
        try:
            # 先检查图书是否存在
            self.cursor.execute("SELECT * FROM books WHERE id = ?", (book_id,))
            if not self.cursor.fetchone():
                return False, "图书不存在"

            # 检查图书是否被借出
            self.cursor.execute("SELECT * FROM books WHERE id = ? AND status = 'borrowed'", (book_id,))
            if self.cursor.fetchone():
                return False, "图书已被借出,无法删除"

            # 删除图书
            self.cursor.execute("DELETE FROM books WHERE id = ?", (book_id,))
            self.conn.commit()
            return True, "图书删除成功"
        except Exception as e:
            return False, f"删除图书失败: {str(e)}"

    def search_books(self, keyword):
        """搜索图书"""
        self.cursor.execute(
            "SELECT * FROM books WHERE title LIKE ? OR author LIKE ? OR isbn LIKE ?",
            (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%")
        )
        return self.cursor.fetchall()

    def list_books(self):
        """列出所有图书"""
        self.cursor.execute("SELECT * FROM books")
        return self.cursor.fetchall()

    # 用户管理功能
    def register_user(self, name, email, password):
        """注册用户"""
        try:
            self.cursor.execute(
                "INSERT INTO users (name, email, password) VALUES (?, ?, ?)",
                (name, email, password)
            )
            self.conn.commit()
            return True, "用户注册成功"
        except sqlite3.IntegrityError:
            return False, "邮箱已被注册"
        except Exception as e:
            return False, f"注册用户失败: {str(e)}"

    def authenticate_user(self, email, password):
        """验证用户身份"""
        self.cursor.execute(
            "SELECT * FROM users WHERE email = ? AND password = ?",
            (email, password)
        )
        return self.cursor.fetchone()

    # 借阅管理功能
    def borrow_book(self, book_id, user_id):
        """借阅图书"""
        from datetime import datetime, timedelta

        try:
            # 检查图书是否存在
            self.cursor.execute("SELECT * FROM books WHERE id = ?", (book_id,))
            book = self.cursor.fetchone()
            if not book:
                return False, "图书不存在"

            # 检查图书是否可借
            if book[4] == 'borrowed':
                return False, "图书已被借出"

            # 更新图书状态
            borrow_date = datetime.now().strftime("%Y-%m-%d")
            due_date = (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d")
            self.cursor.execute(
                "UPDATE books SET status = 'borrowed', borrowed_date = ?, due_date = ? WHERE id = ?",
                (borrow_date, due_date, book_id)
            )

            # 记录借阅信息
            self.cursor.execute(
                "INSERT INTO borrow_records (book_id, user_id, borrow_date) VALUES (?, ?, ?)",
                (book_id, user_id, borrow_date)
            )

            self.conn.commit()
            return True, f"借阅成功,应在 {due_date} 前归还"
        except Exception as e:
            return False, f"借阅失败: {str(e)}"

    def return_book(self, book_id):
        """归还图书"""
        from datetime import datetime

        try:
            # 检查图书是否存在
            self.cursor.execute("SELECT * FROM books WHERE id = ?", (book_id,))
            book = self.cursor.fetchone()
            if not book:
                return False, "图书不存在"

            # 检查图书是否被借出
            if book[4] == 'available':
                return False, "图书未被借出"

            # 更新图书状态
            return_date = datetime.now().strftime("%Y-%m-%d")
            self.cursor.execute(
                "UPDATE books SET status = 'available', borrowed_date = NULL, due_date = NULL WHERE id = ?",
                (book_id,)
            )

            # 更新借阅记录
            self.cursor.execute(
                "UPDATE borrow_records SET return_date = ? WHERE book_id = ? AND return_date IS NULL",
                (return_date, book_id)
            )

            self.conn.commit()

            # 检查是否逾期
            due_date = datetime.strptime(book[6], "%Y-%m-%d")
            if datetime.now() > due_date:
                days_overdue = (datetime.now() - due_date).days
                return True, f"归还成功,但已逾期 {days_overdue} 天"

            return True, "归还成功"
        except Exception as e:
            return False, f"归还失败: {str(e)}"

    def list_borrowed_books(self):
        """列出所有借出的图书"""
        self.cursor.execute("SELECT * FROM books WHERE status = 'borrowed'")
        return self.cursor.fetchall()


# 简单的命令行界面
def main():
    library = LibrarySystem()

    while True:
        print("\n===== 图书管理系统 =====")
        print("1. 添加图书")
        print("2. 删除图书")
        print("3. 搜索图书")
        print("4. 列出所有图书")
        print("5. 注册用户")
        print("6. 用户登录")
        print("7. 借阅图书")
        print("8. 归还图书")
        print("9. 查看借出的图书")
        print("0. 退出系统")

        choice = input("请输入你的选择: ")

        if choice == "1":
            title = input("请输入书名: ")
            author = input("请输入作者: ")
            isbn = input("请输入ISBN(可选,直接回车跳过): ") or None
            success, message = library.add_book(title, author, isbn)
            print(message)

        elif choice == "2":
            book_id = input("请输入要删除的图书ID: ")
            success, message = library.remove_book(int(book_id))
            print(message)

        elif choice == "3":
            keyword = input("请输入搜索关键词: ")
            books = library.search_books(keyword)
            if books:
                for book in books:
                    print(f"ID: {book[0]}, 书名: {book[1]}, 作者: {book[2]}, ISBN: {book[3]}, 状态: {book[4]}")
            else:
                print("未找到匹配的图书")

        elif choice == "4":
            books = library.list_books()
            if books:
                for book in books:
                    print(f"ID: {book[0]}, 书名: {book[1]}, 作者: {book[2]}, ISBN: {book[3]}, 状态: {book[4]}")
            else:
                print("图书馆暂无图书")

        elif choice == "5":
            name = input("请输入姓名: ")
            email = input("请输入邮箱: ")
            password = input("请输入密码: ")
            success, message = library.register_user(name, email, password)
            print(message)

        elif choice == "6":
            email = input("请输入邮箱: ")
            password = input("请输入密码: ")
            user = library.authenticate_user(email, password)
            if user:
                print(f"登录成功,欢迎 {user[1]}!")
                current_user_id = user[0]
            else:
                print("登录失败,邮箱或密码错误")

        elif choice == "7":
            if 'current_user_id' not in locals():
                print("请先登录")
                continue

            book_id = input("请输入要借阅的图书ID: ")
            success, message = library.borrow_book(int(book_id), current_user_id)
            print(message)

        elif choice == "8":
            book_id = input("请输入要归还的图书ID: ")
            success, message = library.return_book(int(book_id))
            print(message)

        elif choice == "9":
            books = library.list_borrowed_books()
            if books:
                for book in books:
                    print(f"ID: {book[0]}, 书名: {book[1]}, 作者: {book[2]}, 借阅日期: {book[4]}, 应还日期: {book[5]}")
            else:
                print("暂无借出的图书")

        elif choice == "0":
            print("感谢使用图书管理系统,再见!")
            library.disconnect()
            break

        else:
            print("无效的选择,请重新输入")


if __name__ == "__main__":
    main()

总结

这个图书管理系统虽然简单,但涵盖了数据库应用的基本要素,包括数据建模、CRUD操作、事务处理和用户界面。它展示了如何使用Python和SQLite构建一个小型但功能完整的应用程序,适合作为学习数据库编程的示例项目。通过进一步扩展和完善,可以发展为一个实用的图书馆管理工具。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不爱说话的分院帽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值