C# WinForm实现图书管理系统:三层架构与完整代码示例

蓝鲸
蓝鲸
发布时间:2026-10-16| 6人浏览过
原创

本文将展示如何利用C#语言和WinForm框架开发一套具备注册、查询、借阅、归还及欠费管理功能的图书管理系统。内容涵盖基于SQL Server的数据库结构设计、三层架构(表示层、业务逻辑层、数据访问层)的代码组织方式,以及关键界面的核心逻辑实现。

系统概述与设计思路

本示例旨在通过模拟真实的图书馆业务场景,帮助理解桌面应用程序与后端数据库的交互机制。系统主要支持两类用户操作:

  • 学生/读者端:账号注册、馆藏图书查询、借书、还书、查看借阅记录及欠费金额查询。
  • 管理员端:通常用于后台管理(本示例重点展示读者端业务流程)。

为了保持代码结构的清晰与可维护性,系统采用经典的三层架构进行分层设计:

  1. 表示层 (Presentation Layer):负责界面显示与用户交互(WinForm窗体)。
  2. 业务逻辑层 (Business Logic Layer):处理核心业务规则(如借书判断、欠费计算)。
  3. 数据访问层 (Data Access Layer):封装对SQL Server数据库的连接、执行SQL语句及结果集获取操作。

数据库环境准备

在开始编码前,需要在SQL Server中创建基础数据结构。以下是创建数据库及五张核心表的完整脚本,并预置了测试数据供调试使用。

第1步:创建数据库与核心表结构

运行以下SQL脚本以初始化环境。注意修改文件路径以适应本地环境。

create database MyLibrary
on
(name=Mylibrary_data1,
filename='d:\Mylibrary_data1.mdf',
size=10,
maxsize=50,
filegrowth=4)
log on
(name=Mylibrary_log1,
filename='d:\Mylibrary_log1.ldf',
size=10MB,
maxsize=20MB,
filegrowth=2MB);

use MyLibrary;

-- 读者表
create table reader(
readerid varchar(20) primary key,
readername varchar(20) not null,
readersex varchar(20) not null,
readertype varchar(20) not null,
readerpd varchar(20) not null
);

-- 图书表
create table book(
bookid varchar(20) primary key,
booktype varchar(20) not null,
bookauthor varchar(20) not null,
bookname varchar(20) not null,
isbrrowed varchar(20) not null,
booklibrary varchar(20) not null,
bookpubdate datetime
);

-- 借阅记录表
create table brrow_data(
readerid varchar(20) primary key,
bookid varchar(20),
bookname varchar(20),
brrowdate datetime,
foreign key (readerid) references reader(readerid),
foreign key (bookid) references book(bookid)
);

-- 归还记录表
create table return_record(
readerid varchar(20) primary key,
bookid varchar(20),
bookname varchar(20),
returndate datetime,
foreign key (readerid) references reader(readerid),
foreign key (bookid) references book(bookid)
);

-- 欠费信息表
create table readerfee(
readerid varchar(20) primary key,
bookid varchar(20),
bookname varchar(20),
readerpay varchar(20),
foreign key (readerid) references reader(readerid),
foreign key (bookid) references book(bookid)
);

-- 插入测试数据(图书)
insert into book values ('3140921000','缥缈之旅','修真','小猪','仙王出版社','2005-09-01','否');
insert into book values ('3140921001','唐朝好男人','穿越','多一半','新星出版社','2005-07-01','否');
insert into book values ('3140921002','鬼吹灯','恐怖','天下霸唱','安徽文艺出版社','2005-09-01','否');
insert into book values ('3140921003','和空姐同居的日子','都市','海王','中国海关出版社','2005-08-01','否');
insert into book values ('3140921004','卡图','科幻','方向','广西人民出版社','2005-06-01','否');
insert into book values ('3140921005','蜀山剑侠传','仙侠','还珠楼主','陕西人民出版社','2005-04-01','否');
insert into book values ('3140921006','何以笙箫默','言情','顾漫','朝华出版社','2005-05-01','否');
insert into book values ('3140921007','步步惊心','穿越','童话','民族出版社','2005-12-01','否');

-- 插入测试数据(读者)
insert into reader values ('21007000','李磊','男','学生','000000');
insert into reader values ('21007001','棠张僧','男','学生','000000');
insert into reader values ('21007002','韩梅梅','女','学生','000000');
insert into reader values ('21007003','路西','女','学生','000000');
insert into reader values ('21007004','王强','男','学生','000000');
insert into reader values ('21007005','马正标','男','管理','000000');
insert into reader values ('21007006','卢海鹏','男','管理','000000');
insert into reader values ('21007007','李艳玲','女','管理','000000');

客户端界面与核心逻辑实现

第1步:登录模块开发

登录界面是系统的入口,主要负责验证用户身份并跳转至对应权限的界面。实际生产中建议使用参数化查询防止SQL注入,此处为教学目的展示基本逻辑。

登录界面布局示意:

登录按钮与连接初始化核心代码:

using System;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Library
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 简单演示:点击登录后直接进入学生主界面(省略了详细的密码校验逻辑,实际应用需补充)
            Form2 form2 = new Form2();
            this.Hide();
            form2.Show();
            mycon.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 建立数据库连接配置
            string con = "Server=.;Database=MyLibrary;Trusted_Connection=SSPI";
            mycon = new SqlConnection(con);
            mycon.Open();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form3 form3 = new Form3();
            this.Hide();
            form3.Show();
        }
    }
}

第2步:新用户注册逻辑

注册页面用于新增读者账号,包含基本的非空校验和重复账号检测。

注册界面布局示意:

注册提交事件代码:

using System;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Library
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 检查账号是否已存在
            string sql = string.Format("select count(*) from reader where readerid='{0}'", textBox1.Text);
            SqlCommand com = new SqlCommand(sql, mycon);
            int count = (int)com.ExecuteScalar();
            
            if (count == 1)
            {
                MessageBox.Show("抱歉,该账号已存在!");
            }
            else
            {
                // 检查必填字段是否为空
                if (textBox1.Text=="" || textBox2.Text=="" || textBox4.Text=="" || comboBox1.Text=="" || textBox3.Text=="")
                {
                    MessageBox.Show("请将信息填写完整!");
                }
                else
                {
                    // 此处应添加 INSERT INTO reader ... 实际写入代码
                    MessageBox.Show("注册成功!请返回登录。");
                    Form1 form1 = new Form1();
                    form1.Show();
                    this.Hide();
                }
            }
        }

        private void Form3_Load(object sender, EventArgs e)
        {
            string con = "Server=.;Database=MyLibrary;Trusted_Connection=SSPI";
            mycon = new SqlConnection(con);
            mycon.Open();
        }
    }
}

第3步:学生主界面功能实现

这是系统的核心区域,包含个人信息查看、图书检索、借还操作及欠费缴纳等功能。

学生管理主界面示意:

主要功能代码逻辑:

  • 数据查询:利用 SqlDataAdapter 填充 DataSet 并绑定至 DataGridView。
  • 借书逻辑:输入书名 -> 查询是否存在 -> 插入借阅记录表。
  • 还书逻辑:输入书号 -> 确认借阅状态 -> 插入归还记录 -> 删除借阅记录。
  • 欠费计算:根据当前日期与借出日期的差值,超过30天部分按每天0.3元累计。

核心操作事件代码:

using System;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Library
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public string readerid; // 当前登录用户的ID
        string sql, con;
        SqlConnection mycon;
        SqlCommand com;

        private void Form2_Load(object sender, EventArgs e)
        {
            // 初始化界面隐藏项
            label1.Hide(); textBox1.Hide(); button4.Hide();
            dataGridView1.Hide();
            
            con = "Server=.;Database=MyLibrary;Trusted_Connection=SSPI";
            mycon = new SqlConnection(con);
            mycon.Open();
        }

        // 查看个人信息
        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.Show();
            sql = string.Format("select * from reader where readerid='{0}'", readerid);
            LoadData(sql);
        }

        // 查看所有图书
        private void button2_Click(object sender, EventArgs e)
        {
            dataGridView1.Show();
            sql = "select * from book";
            LoadData(sql);
        }

        // 缴缴费功能
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                // 计算超期罚款逻辑:超过30天,每天0.3元
                string calcSql = string.Format(
                    "insert into readerfee(readerid,bookid,bookname,readerpay) select readerid ,bookid , bookname, 
                    0.03*(datediff(day,convert(smalldatetime,brrowdate),getdate())-30) 
                    from brrow_data where datediff(day,convert(smalldatetime,brrowdate),getdate())>=0;");
                
                com = new SqlCommand(calcSql, mycon);
                com.ExecuteNonQuery();
            }
            catch { }

            // 显示当前用户的费用列表
            string querySql = string.Format("select * from readerfee where readerid='{0}'", readerid);
            LoadData(querySql);
        }

        // 借书/还书切换菜单响应
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataGridView1.Hide();
            if (comboBox2.Text == "我要借书")
            {
                button4.Show();
                button4.Text = "借阅本书";
                label1.Text = "搜索书名";
                label1.Show();
                textBox1.Show();
            }
            else if (comboBox2.Text == "我要还书")
            {
                button4.Show();
                button4.Text = "归还本书";
                label1.Text = "所借书号";
                label1.Show();
                textBox1.Show();
            }
        }

        // 执行借书或还书操作
        private void button4_Click(object sender, EventArgs e)
        {
            if (button4.Text == "借阅本书")
            {
                // 1. 检查图书是否存在
                sql = string.Format("select count(*) from book where bookname='{0}'", textBox1.Text);
                com = new SqlCommand(sql, mycon);
                int count = (int)com.ExecuteScalar();

                if (count >= 1)
                {
                    // 2. 获取BookId
                    sql = string.Format("select bookid from book where bookname='{0}'", textBox1.Text);
                    com = new SqlCommand(sql, mycon);
                    string bookid = (string)com.ExecuteScalar();

                    // 3. 插入借阅记录
                    sql = string.Format("insert into brrow_data (readerid,bookid,bookname,brrowdate) values('{0}','{1}','{2}','{3}')",
                        readerid, bookid, textBox1.Text, DateTime.Now);
                    com = new SqlCommand(sql, mycon);
                    com.ExecuteNonQuery();
                    MessageBox.Show("借书成功!");
                }
                else
                {
                    MessageBox.Show("抱歉,不存在本书!");
                }
            }
            else if (button4.Text == "归还本书")
            {
                // 1. 检查是否存在未还记录
                sql = string.Format("select count(*) from brrow_data where bookid='{0}'", textBox1.Text);
                com = new SqlCommand(sql, mycon);
                int count = (int)com.ExecuteScalar();

                if (count >= 1)
                {
                    // 2. 获取书名用于记录
                    sql = string.Format("select bookname from brrow_data where bookid='{0}'", textBox1.Text);
                    com = new SqlCommand(sql, mycon);
                    string bookname = (string)com.ExecuteScalar();

                    // 3. 插入归还记录
                    sql = string.Format("insert into return_record(readerid,bookid,bookname,returndate) values ('{0}','{1}','{2}','{3}')",
                        readerid, textBox1.Text, bookname, DateTime.Now);
                    com = new SqlCommand(sql, mycon);
                    com.ExecuteNonQuery();

                    // 4. 清除借阅记录
                    sql = string.Format("delete from brrow_data where bookid='{0}'", textBox1.Text);
                    com = new SqlCommand(sql, mycon);
                    com.ExecuteNonQuery();

                    MessageBox.Show(bookname + " 还书成功!");
                }
                else
                {
                    MessageBox.Show("抱歉!您没有借这本书!");
                }
            }
        }

        // 辅助方法:加载数据到 DataGridView
        private void LoadData(string querySql)
        {
            SqlDataAdapter mydata = new SqlDataAdapter(querySql, con);
            DataSet myds = new DataSet();
            mydata.Fill(myds, "result");
            dataGridView1.DataSource = myds.Tables[0];
        }
    }
}

总结与维护建议

通过上述步骤,我们实现了一个基础的图书管理系统原型。该系统展示了如何从底层数据库设计到上层UI交互的完整开发流。在实际生产环境中,建议在以下几个方向进行优化:

  • 安全性:原文中的字符串拼接SQL容易遭受SQL注入攻击,强烈建议全面替换为 SqlParameter 参数化查询。
  • 架构分离:目前的代码将所有逻辑写在WinForm中,实际项目应将数据库操作移至DAL,将计费等业务规则移至BLL,保持代码整洁。
  • 异常处理:增加更细致的Try-Catch块,捕获具体的SQL错误或网络断开情况,并向用户反馈友好的错误信息。
以上就是利用C#实现图书管理系统的详细内容,更多关于C# WinForm数据库开发及三层架构设计的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。