【C#项目】图书馆管理系统-WinForm+MySQL
文章目录
- 前言
- 一、业务梳理与需求分析
- 1.功能描述
- 2.实现步骤
- 3.功能逻辑图
- 二、数据库设计
- 1.实体-关系(E-R图)概念模型设计
- 2.数据表设计
- 三、WinForm界面交互设计
- 1、界面交互逻辑
- 2、项目树
- 3、主界面+登录界面
- 4、 图书查询界面
- 5、图书借阅界面
- 6、图书插入界面
- 7、图书更新/删除界面
- 四、通用类设计
- 1、与MySQL通讯模块(整个类模块中删除命名空间等,值保留这个类)
- 2、数据库操作模块:
- 五、系统代码实现与分析
- 1、主界面代码:
- 2、登录界面代码
- 3、图书查询模块代码
- 4、图书借阅代码
- 5、图书插入代码
- 6、图书更新/删除代码
- 总结
前言
图书馆管理系统主要功能有普通用户(学生)借书、管理员管理图书。
一、业务梳理与需求分析
1.功能描述
- 系统中的普通用户模块有以下功能:
图书查询:根据输入的搜索条件进行查询,可以查找多项,也可以查找所有图书。
图书借阅:提供图书借阅证号,可以进行图书借阅。 - 系统中的管理员用户模块有以下功能:
图书查询:查询图书信息。
图书借阅:提供图书借阅证号,可以进行图书借阅。
增加图书:增添新图书。
修改图书:对图书信息进行修改。
删除图书:删除过时的、不能借阅的图书。
2.实现步骤
- 一个完整系统的数据库设计。
- 图书馆管理系统的界面设计。
- 项目的通用类。
- 图书馆管理系统代码的实现和分析。
3.功能逻辑图
二、数据库设计
1.实体-关系(E-R图)概念模型设计
2.数据表设计
根据需求分析进行数据库设计,数据库名称为BookManage,根据E-R图,有学生表、图书信息表、管理员表、借阅表。学生和管理员合并为一张用户表,增加一个字段用户权限进行区分。
-
用户表结构
- 图书信息表结构
- 图书借阅信息表结构
三、WinForm界面交互设计
1、界面交互逻辑
2、项目树
3、主界面+登录界面
4、 图书查询界面
5、图书借阅界面
6、图书插入界面
7、图书更新/删除界面
四、通用类设计
1、与MySQL通讯模块(整个类模块中删除命名空间等,值保留这个类)
public static class DBModule
{public static string ServerIP = "**.**.**.**";public static string ServerPort = "****";public static string ServerUser = "****";public static string ServerPassword = "****";public static string ServerDBName = "bookmanage";
}
2、数据库操作模块:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using System.Data;public class MySQLHelper
{private MySqlConnection myConnection;private string mErrorString;//构造函数public MySQLHelper(string strServerIP, string strServerPort, string strServerUser, string strPassword, string strDBName){string strConnectionString = String.Format("server={0}; port={1}; user id={2}; password={3}; database={4}", strServerIP, strServerPort, strServerUser, strPassword, strDBName);myConnection = new MySqlConnection(strConnectionString);}//测试连接public bool ConnectionTest(){bool result = false;try{if (myConnection.State == System.Data.ConnectionState.Closed){myConnection.Close();result = true;}}catch (MySqlException ex){mErrorString = ex.ToString();}return result;}/// <summary>/// 执行查询语句,用DataTable返回结果,调用前要传入DataTable的实例化对象作为参数/// </summary>/// <param name="strQuery">查询命令</param>/// <param name="dt">返回数据表</param>/// <returns></returns>public bool ExcuteQuerySql(string strQuery, ref DataTable dt){if (dt == null){mErrorString = "传入的DataTable为null";return false;}bool result = false;try{MySqlCommand myCommand = new MySqlCommand(strQuery);myCommand.Connection = myConnection;if (myConnection.State == ConnectionState.Closed){myConnection.Open();}dt.Load(myCommand.ExecuteReader());result = true;}catch (MySqlException ex){mErrorString = String.Format("ExcuteQuery {0} failed.", ex.ToString());return false;}finally{myConnection.Close();}return result;}/// <summary>/// 执行带参数的查询语句,使用前传入参数、DataTable实例化对象/// </summary>/// <param name="strQuery">查询语句</param>/// <param name="param"></param>/// <param name="dt"></param>/// <returns></returns>public bool ExcuteQuerySql(string strQuery, MySqlParameter[] param, ref DataTable dt){if (dt == null){mErrorString = "传入的DataTable为null.";return false;}bool result = false;try{MySqlCommand myCommand = new MySqlCommand(strQuery);myCommand.Connection = myConnection;if (myConnection.State == ConnectionState.Closed){myConnection.Open();}for (int i = 0; i < param.Length; i++){myCommand.Parameters.Add(param[i]);}dt.Load(myCommand.ExecuteReader());result = true;}catch (MySqlException ex){mErrorString = String.Format("ExcuteQuery {0} failed", strQuery) + ex.Message;return false;}finally{myConnection.Close();}return result;}//执行非查询语句public int ExcuteSql(string SqlCmdText){int row = -1;try{MySqlCommand myCommand = new MySqlCommand(SqlCmdText);myCommand.CommandText = SqlCmdText;myCommand.Connection = myConnection;if (myConnection.State == ConnectionState.Closed){myConnection.Open();}row = myCommand.ExecuteNonQuery();}catch (MySqlException ex){mErrorString = String.Format("ExcuteNonQuery {0} failed", SqlCmdText);}return row;}//执行非查询语句public int ExcuteSql(string[] SqlCmdText){try{if (myConnection.State == ConnectionState.Closed){myConnection.Open();}for (int i = 0; i < SqlCmdText.Length; i++){MySqlCommand myCommand = new MySqlCommand(SqlCmdText[i]);myCommand.CommandText = SqlCmdText[i];myCommand.Connection = myConnection;myCommand.ExecuteNonQuery();}}catch (MySqlException ex){mErrorString = String.Format("ExcuteNonQuery {0} failed", SqlCmdText) + ex.Message;return -1;}return -1;}//执行带参数的非查询语句public int ExcuteSql(string SqlCmdText, MySqlParameter[] param){int row = -1;try{MySqlCommand myCommand = new MySqlCommand(SqlCmdText);myCommand.CommandText = SqlCmdText;myCommand.Connection = myConnection;if (myConnection.State == ConnectionState.Closed){myConnection.Open();}for (int i = 0; i < param.Length; i++){myCommand.Parameters.Add(param[i]);}row = myCommand.ExecuteNonQuery();}catch (MySqlException ex){mErrorString = String.Format("ExecuteNonQuery {0} failed", SqlCmdText) + ex.Message;return row = -1;}return row;}public string GetErrInfo(){return mErrorString;}
}
五、系统代码实现与分析
1、主界面代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmMain : Form{public static DialogResult result;//声明对话框返回对象public FrmMain(){InitializeComponent();}/// <summary>/// 查询子窗体是否存在/// </summary>/// <param name="childfrmname"></param>/// <returns></returns>public bool CheckChildFrm(string childfrmname){foreach (Form childFrm in this.MdiChildren)//遍历子窗体{if (childFrm.Name == childfrmname)//如果子窗体存在{if (childFrm.WindowState == FormWindowState.Minimized){childFrm.WindowState = FormWindowState.Normal;}childFrm.Activate();//激活该窗体return true; //存在返回true}}return false;//不存在返回false}/// <summary>/// 用户登录菜单的事件处理/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void 用户登录ToolStripMenuItem_Click(object sender, EventArgs e){//检测登录窗口是否打开if (this.CheckChildFrm("FrmLogin") == true){return;//窗口已经打开,返回}FrmLogin user = new FrmLogin();//实例化登录窗体user.ShowDialog();//登录窗体以模式对话框的方式打开//判断是否登录成功,登录成功则启用相应的菜单和按钮if (result == System.Windows.Forms.DialogResult.OK && FrmLogin.ustate == 0)//普通用户{toolSBSearch.Enabled = true;toolSBBookBorown.Enabled = true;}else if (result == System.Windows.Forms.DialogResult.OK && FrmLogin.ustate == 1)//管理员{toolSBSearch.Enabled = true;toolSBBookBorown.Enabled = true;toolMBookManage.Enabled = true;}}/// <summary>/// 用户登录按钮事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void toolSBLogin_Click(object sender, EventArgs e){//检测登录窗口是否打开if (this.CheckChildFrm("FrmLogin") == true){return;//窗口已经打开,返回}FrmLogin user = new FrmLogin();//实例化登录窗体user.ShowDialog();//登录窗体以模式对话框的方式打开//判断是否登录成功,登录成功则启用相应的菜单和按钮if (result == System.Windows.Forms.DialogResult.OK && FrmLogin.ustate == 0)//普通用户{//普通用户登录后使能按钮toolSBSearch.Enabled = true;toolSBBookBorown.Enabled = true;}else if (result == System.Windows.Forms.DialogResult.OK && FrmLogin.ustate == 1)//管理员{//管理员登录后使能按钮toolSBSearch.Enabled = true;toolSBBookBorown.Enabled = true;toolMBookManage.Enabled = true;}}/// <summary>/// 图书查询按钮,转到图书查询界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void toolSBSearch_Click(object sender, EventArgs e){if (this.CheckChildFrm("FrmBookSearch") == true){return;}FrmBookSearch frmBookSearch = new FrmBookSearch();frmBookSearch.MdiParent = this;//设置当前窗体的子窗体为frmBookSearchfrmBookSearch.Show();}/// <summary>/// 图书借阅按钮,转到图书借阅界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void toolSBBookBorown_Click(object sender, EventArgs e){if (this.CheckChildFrm("FrmBookBrown") == true){return;}FrmBookBrown frmBookBrown = new FrmBookBrown();frmBookBrown.MdiParent = this;//设置当前窗体的子窗体为frmBookBrownfrmBookBrown.Show();}/// <summary>/// 图书插入按钮,转到图书插入界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void toolMBookIn_Click(object sender, EventArgs e){if (this.CheckChildFrm("FrmBookIn") == true){return;}FrmBookIn frmBookIn = new FrmBookIn();frmBookIn.MdiParent = this;//设置当前窗体的子窗体为frmBookInfrmBookIn.Show();}/// <summary>/// 图书更新/删除按钮,转到图书更新与删除界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void toolMBookUpdate_Click(object sender, EventArgs e){if (this.CheckChildFrm("FrmUpdateBook") == true){return;}FrmUpdateBook frmUpdateBook = new FrmUpdateBook();frmUpdateBook.MdiParent = this;//设置当前窗体的子窗体为frmUpdateBookfrmUpdateBook.Show();}private void toolSBExit_Click(object sender, EventArgs e){if (MessageBox.Show("确认退出程序?", "确认信息", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK){System.Environment.Exit(0);}}}
}
2、登录界面代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmLogin : Form{public FrmLogin(){InitializeComponent();}public static int ustate;//普通用户or管理员标志FrmMain femmain = new FrmMain();private void btnLogin_Click(object sender, EventArgs e){//输入合法性判断if (Volidity())//合法性通过{string state = this.cmbUserType.Text;int num;if (state.Equals("管理员"))//判断用户角色{num = 1;}else{num = 2;}//定义查询语句string sql = String.Format("select * from user where uname='{0}' and upwd='{1}' and ustate='{2}'", this.txtUserName.Text.Trim(), this.txtPwd.Text.Trim(), num);MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);DataTable dt = new DataTable();bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dt);if (queryFlag == false){MessageBox.Show("登录失败,没有找到该用户");}if (dt.Rows.Count > 0){MessageBox.Show("登录成功!");FrmMain.result = DialogResult.OK;//为变量result赋值DBModule.UserName = txtUserName.Text;this.Close();}else{MessageBox.Show("用户名或密码错误,请重新输入");}}}/// <summary>/// 验证合法性/// </summary>private bool Volidity(){if (this.txtPwd.Text != string.Empty && this.txtPwd.Text != string.Empty){return true;}else{MessageBox.Show("用户名或密码不能为空");}return false;}private void btnCancel_Click(object sender, EventArgs e){this.Close();}private void cmbUserType_SelectedIndexChanged(object sender, EventArgs e){if (cmbUserType.SelectedIndex == 0){cmbUserType.Text = "普通用户";ustate = 0;}else{cmbUserType.Text = "管理员";ustate = 1;}}private void FromLogin_Load(object sender, EventArgs e){this.cmbUserType.SelectedIndex = 0;ustate = 0;}}
}
3、图书查询模块代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmBookSearch : Form{public FrmBookSearch(){InitializeComponent();}private void btnSearch_Click(object sender, EventArgs e){string strBookType = cmbBokTyp.Text;string strBookTypeOr = cmbBokTypOr.Text;string strBookName = txtBokNm.Text;string strBookNameOr = txtBokNmOr.Text;string strBookConment = txtBokCotnt.Text;//定义sql语句string sql = "SELECT * FROM book WHERE booktype='" + strBookType + "'" + "or booktype='" + strBookTypeOr + "'" + " and bookname='" + strBookName + "';";MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);DataTable dt = new DataTable();bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dt);if (queryFlag == false){MessageBox.Show("查询失败,没有该图书信息");}if (dt.Rows.Count > 0){dgvBookSearch.DataSource = dt;}//设置列名标题string[] strColumnName = { "图书ID", "图书类别", "书名", "作者", "价格", "封面", "内容简介", "指定访问码"};for (int i = 0; i < dgvBookSearch.Columns.Count; i++){dgvBookSearch.Columns[i].HeaderText = strColumnName[i];}}private void btnClose_Click(object sender, EventArgs e){this.Close();}private void FrmBookSearch_Load(object sender, EventArgs e){//图书类别的初始化string sql = "SELECT DISTINCT booktype FROM book;";MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);DataTable dtTtpe = new DataTable();try{bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dtTtpe);if (queryFlag == false){MessageBox.Show("查询图书类型失败");}}catch (Exception ex){MessageBox.Show("查询图书类型失败" + ex.ToString());}if (dtTtpe.Rows.Count > 0){for (int i = 0; i < dtTtpe.Rows.Count; i++){this.cmbBokTyp.Items.Add(dtTtpe.Rows[i][0].ToString());this.cmbBokTypOr.Items.Add(dtTtpe.Rows[i][0].ToString());}}this.cmbBokTyp.SelectedIndex = 0;this.cmbBokTypOr.SelectedIndex = 0;}}
}
4、图书借阅代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmBookBrown : Form{public FrmBookBrown(){InitializeComponent();}DataTable dt = new DataTable();MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);/// <summary>/// 图书借阅按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnBrown_Click(object sender, EventArgs e){//获取下拉框中选中图书的IDint bookid = Convert.ToInt32(this.cmbBookName.SelectedIndex + 1);//获取用户的借阅证int issid = Convert.ToInt32(this.txtIssueID.Text);//获取借阅时间DateTime date = Convert.ToDateTime(this.IssDatetime.Text);//更新借阅信息string sql = "insert into bookbrown (bookid, issbookid, issdatetime) values ('" + bookid + "', '" + issid + "', '" + date + "');";//借阅信息中没有这本书才可借阅DataTable dtC = new DataTable();sqlHelper.ExcuteQuerySql("select bookid from bookbrown;", ref dtC);int flagTmp = 0;for (int i = 0; i < dtC.Rows.Count; i++){if (Convert.ToInt32(dtC.Rows[i][0].ToString()) == bookid){flagTmp = 1;}}if (flagTmp == 1){MessageBox.Show("这本书你已经借阅过,借阅不能超过1本", "提示信息", MessageBoxButtons.OK);}else{if (sqlHelper.ExcuteSql(sql) == 1){MessageBox.Show("借阅成功");}else{MessageBox.Show("借阅失败");}}//刷新借阅证中的图书信息string sqlQ = "select bookinfo.bookid,bookname,issbookid,issdatetime from bookbrown,bookinfo where bookinfo.bookid=bookbrown.bookid;";bool queryFlagQ = sqlHelper.ExcuteQuerySql(sqlQ, ref dt);if (queryFlagQ == true){this.dataGridView1.DataSource = dt;}}private void btnCancel_Click(object sender, EventArgs e){this.Close();}private void FrmBookBrown_Load(object sender, EventArgs e){string sql = "select * from bookinfo;";//联合图书信息表、借阅信息表查询string sqlBro = "select bookinfo.bookid,bookname,issbookid,issdatetime from bookbrown,bookinfo where bookinfo.bookid=bookbrown.bookid;"; //主键与外键的关联try{bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dt);//查询图书信息if (queryFlag == false){MessageBox.Show("查询失败");}else{//自动加载图书名到下拉框for (int i = 0; i < dt.Rows.Count; i++){this.cmbBookName.Items.Add(dt.Rows[i][1].ToString());}}//联合查询查询本人借阅信息DataTable dtBro=new DataTable();bool queryFlagBro = sqlHelper.ExcuteQuerySql(sqlBro, ref dtBro);if (queryFlagBro == true){this.dataGridView1.DataSource = dtBro;}else{MessageBox.Show("查询借阅信息失败");}//查询用户信息 string sqlU = "select * from user where uname= '" + DBModule.UserName + "';";DataTable dtU = new DataTable();bool queryFlagU = sqlHelper.ExcuteQuerySql(sqlU, ref dtU);if (queryFlagU == true){this.txtUserName.Text = dtU.Rows[0]["uname"].ToString();this.txtIssueID.Text = dtU.Rows[0]["upwd"].ToString();}//初始化列名string[] strColumnName = { "图书编号", "图书名称", "指定访问码", "借阅时间"};for (int i = 0; i < dt.Columns.Count; i++){dataGridView1.Columns[i].HeaderText=strColumnName[i];}}catch (Exception ex){MessageBox.Show(""); }}/// <summary>/// 图书名称选项变化的事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void cmbBookName_SelectedIndexChanged(object sender, EventArgs e){//遍历图书信息表,查询和选中书名相同的信息,加载到界面foreach (DataRow row in dt.Rows){if (cmbBookName.Text == row["bookname"].ToString()){this.txtBookIssue.Text = row["bookissue"].ToString();this.txtBookAuthor.Text = row["bookauthor"].ToString();}}}}
}
5、图书插入代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmBookIn : Form{public FrmBookIn(){InitializeComponent();}/// <summary>/// 图书插入按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnInsert_Click(object sender, EventArgs e){//定义变量接收控件的值string strBookType = txtBookType.Text;string strBookName = txtBookName.Text;string strAuthor = txtAuthor.Text;string strPrice = txtPrice.Text;string strPic = txtPic.Text;string strContent = txtContent.Text;string strIssue = txtIssue.Text;if (Vaildate()){//sql语句string sql = "insert into bookinfo (bookname, booktype, bookauthor, bookprice, bookpic, bookcontent, bookissue)"+ " values ('" + strBookName + "', '" + strBookType + "', '" + strAuthor + "', '" + strPrice + "', '" + strPic + "', '" + strContent + "', '" + strIssue + "');";MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);int result=sqlHelper.ExcuteSql(sql);if (result == 1){MessageBox.Show("添加成功", "提示", MessageBoxButtons.OK);}else{MessageBox.Show("添加失败", "提示", MessageBoxButtons.OK);}DataTable dt = new DataTable();sqlHelper.ExcuteQuerySql("select * from bookinfo;", ref dt);this.dataGridView1.DataSource = dt;//设置列名标题string[] strColumnName = { "图书ID", "图书类别", "书名", "作者", "价格", "封面", "内容简介", "指定访问码" };for (int i = 0; i < dataGridView1.Columns.Count; i++){dataGridView1.Columns[i].HeaderText = strColumnName[i];}}}/// <summary>/// 退出图书界面按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnExit_Click(object sender, EventArgs e){this.Close();}/// <summary>/// 输入合法性验证/// </summary>/// <returns></returns>private bool Vaildate(){if (txtBookType.Text != string.Empty && txtBookName.Text != string.Empty && txtAuthor.Text != string.Empty&& txtPrice.Text != string.Empty && txtPic.Text != string.Empty && txtContent.Text != string.Empty && txtIssue.Text != string.Empty){return true;}else{MessageBox.Show("请出入完整信息");}return false;}}
}
6、图书更新/删除代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace BookManage
{public partial class FrmUpdateBook : Form{public FrmUpdateBook(){InitializeComponent();}MySQLHelper sqlHelper = new MySQLHelper(DBModule.ServerIP, DBModule.ServerPort, DBModule.ServerUser, DBModule.ServerPassword, DBModule.ServerDBName);/// <summary>/// 保存信息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSave_Click(object sender, EventArgs e){string sql = "select * from bookinfo;";DataTable dt = new DataTable();if (MessageBox.Show("确实要将修改保存到数据库?", "提示信息", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK){bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dt);if (queryFlag == true){MessageBox.Show("保存成功");}this.dataGridView1.DataSource = dt;}//设置列名标题string[] strColumnName = { "图书ID", "图书类别", "书名", "作者", "价格", "封面", "内容简介", "指定访问码" };for (int i = 0; i < dataGridView1.Columns.Count; i++){dataGridView1.Columns[i].HeaderText = strColumnName[i];}}/// <summary>/// 更新信息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnUpdate_Click(object sender, EventArgs e){string strBookType = txtBookType.Text;string strBookName = txtBookName.Text;string strBookAuthor = txtBookAuthor.Text;string strBookPrice = txtBookPrice.Text;string strBookPic = txtBookPic.Text;string strBookContent = txtBookContent.Text;string strBookIssue = txtBookIssue.Text;if (true){string sql = string.Format("update bookinfo set booktype='{0}', bookname='{1}', bookauthor='{2}', bookprice='{3}', bookpic='{4}', bookcontent='{5}',bookissue='{6}' where bookid={7};",strBookType, strBookName, strBookAuthor, strBookPrice, strBookPic, strBookContent, strBookIssue, Convert.ToInt32(txtBookID.Text));if (sqlHelper.ExcuteSql(sql) == 1){MessageBox.Show("更新成功", "提示信息", MessageBoxButtons.OK);}else{MessageBox.Show("更新失败", "提示信息", MessageBoxButtons.OK);}}}/// <summary>/// 删除信息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnDelete_Click(object sender, EventArgs e){if (this.txtBookID.Text != string.Empty){string sql = "select * from bookbrown where bookid=" + Convert.ToInt32(txtBookID.Text) + "";DataTable dt = new DataTable();bool queryFlag = sqlHelper.ExcuteQuerySql(sql, ref dt);if (queryFlag == true && dt.Rows.Count > 0){MessageBox.Show("此书有借阅,不能删除");}else{string sqlDe = "delete from bookinfo where bookid=" + this.txtBookID.Text + "";if (sqlHelper.ExcuteSql(sqlDe) == 1){MessageBox.Show("删除成功", "提示信息", MessageBoxButtons.OK);}else{MessageBox.Show("删除失败", "提示信息", MessageBoxButtons.OK);}}}}/// <summary>/// 取消/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnCancel_Click(object sender, EventArgs e){}/// <summary>/// 验证输入合法性/// </summary>/// <returns></returns>private bool Vaildate(){if (txtBookType.Text != string.Empty && txtBookName.Text != string.Empty && txtBookAuthor.Text != string.Empty&& txtBookPrice.Text != string.Empty && txtBookPic.Text != string.Empty&& txtBookContent.Text != string.Empty && txtBookIssue.Text != string.Empty && txtBookID.Text != string.Empty){return true;}else{MessageBox.Show("请出入完整信息");}return false;}}
}
总结
本项目实现一个简单的图书馆管理系统,是一个完整的图书馆管理系统的简化版。通过这个项目,了解整个桌面应用软件的规范化开发流程,业务梳理、需求分析、概要设计、详细设计、数据库设计、界面交互设计、详细代码设计等步骤。同时将代码开发规范融入其中,尽量使用较为规范的代码。加深了对WinForm界面控件的认识,对MySQL更加熟悉。数据库SQL语言操作还需要多联系,纸上得来终觉浅,觉知此事要躬行。SQL语句看似简单,实际操作起来是出问题最多的地方。
相关文章:

【C#项目】图书馆管理系统-WinForm+MySQL
文章目录前言一、业务梳理与需求分析1.功能描述2.实现步骤3.功能逻辑图二、数据库设计1.实体-关系(E-R图)概念模型设计2.数据表设计三、WinForm界面交互设计1、界面交互逻辑2、项目树3、主界面登录界面4、 图书查询界面5、图书借阅界面6、图书插入界面7、…...

RNN循环神经网络原理理解
一、基础 正常的神经网络 一般情况下,输入层提供数据,全连接进入隐藏层,隐藏层可以是多层,层与层之间是全连接,最后输出到输出层;通过不断的调整权重参数和偏置参数实现训练的效果。深度学习的网络都是水…...
一句话设计模式1: 单例模式
单例模式:全局唯一的对象。 文章目录 单例模式:全局唯一的对象。前言一、为什么要全局唯一?二、如何实现单例1. 注入到spring中2. 饿汉式3. 懒汉式第一种: 静态内部类第二种: synchronized 关键字第二种: 双重锁检查总结前言 单例可以说是设计模式中很常用的模式了,但也可以说…...

新版国家标准GB/T 28181—2022将于2023年7月1日正式实施,与GB/T 28181—2016差别有哪些?
新版国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》已于2022年12月30日发布,将于2023年7月1日正式实施。与GB/T 28181—2016相比,除结构调整和编辑性改动外,主要技术变化如下。——更改了标准范围…...

剑指 Offer 41. 数据流中的中位数
题目 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 例如,[2,3,4] 的中位数是…...
分布式架构下,Session共享有什么方案?
分布式架构下,Session共享有什么方案? 1.不要有Session:但是确实在某些场景下,是可以没有session的,其实在很多借口类系统当中,都提倡【API无状态服务】; 也就是每一次的接口访问,都…...

瀚博半导体载天VA1 加速卡安装过程
背景: 想用 瀚博半导体载天VA1 加速卡 代替 NVIDIA 显卡跑深度学习模型 感谢瀚博的周工帮助解答。 正文: 小心拔出 NVIDIA 显卡,在PCIe 接口插上瀚博半导体载天VA1加速卡,如图: 这时显示屏连接主板的集成显卡 卸载…...

服务降级和熔断机制
🏆今日学习目标: 🍀服务降级和熔断机制 ✅创作者:林在闪闪发光 ⏰预计时间:30分钟 🎉个人主页:林在闪闪发光的个人主页 🍁林在闪闪发光的个人社区,欢迎你的加入: 林在闪闪…...

史上最全最详细的Instagram 欢迎消息引流及示例
史上最全最详细的Instagram 欢迎消息引流及示例!关键词: Instagram 欢迎消息SaleSmartly(ss客服) 寻找 Instagram 欢迎消息示例,您可以用于您的业务。在本文中,我们将介绍Instagram欢迎消息的基础知识和好处…...

MDB 5 UI-KIT Bootstrap 5 最新版放送
顶级开源 UI 套件,Bootstrap v5 和 v4 的材料设计,jQuery 版本,数百个优质组件和模板,所有一致的,有据可查的,可靠的超级简单,1分钟安装简单的主题和定制 受到超过 3,000,000 名开发人员和设计师…...

做专家型服务者,尚博信助力企业数字化转型跑出“加速度” | 爱分析调研
01 从技术应用到业务重构,数字化市场呼唤专家型厂商 企业数字化转型是一个长期且系统性的变革过程。伴随着企业从信息化建设转向业务的数字化重构,市场对数字化厂商的能力要求也在升级。 早期的信息化建设主要是从技术视角切入,采用局部需求…...

CSS 重新认识 !important 肯定有你不知道的
重新认识 !important 影响级联规则 与 animation 和 transition 的关系级联层cascade layer内联样式!important 与权重 !important 与简写属性!important 与自定义变量!important 最佳实践 在开始之前, 先来规范一下文中的用于, 首先看 W3C 中关于 CSS 的一些术语定义吧. 下图…...
android 12添加系统字体并且设置为默认字体
需求:在11.0 12.0系统定制化开发中,在产品定制中,有产品需求对于系统字体风格不太满意,所以想要更换系统的默认字体,对于系统字体的修改也是常有的功能,而系统默认也支持增加字体,所以就来添加楷…...
LeetCode刷题系列 -- 1094. 拼车
车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向)给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客,接他们和放他们的…...

二叉查找树的应用 —— K模型和KV模型
文章目录前言1. K模型2. KV模型🍑 构建KV模型的树🍑 英汉词典🍑 统计水果出现的次数3. 总结前言 在上一篇文章中,我们进行了二叉查找树的实现(文章链接),那么今天主要探讨一下二叉查找树的应用…...

深度学习实战(11):使用多层感知器分类器对手写数字进行分类
使用多层感知器分类器对手写数字进行分类 1.简介 1.1 什么是多层感知器(MLP)? MLP 是一种监督机器学习 (ML) 算法,属于前馈人工神经网络 [1] 类。该算法本质上是在数据上进行训练以学习函数。给定一组特征和一个目标变量&#x…...
ThingsBoard-警报
1、使用 IoT 设备警报 ThingsBoard 提供了创建和管理与您的实体相关的警报的能力:设备、资产、客户等。例如,您可以将 ThingsBoard 配置为在温度传感器读数高于某个阈值时自动创建警报。当然,这是一个非常简化的案例,实际场景可能要复杂得多。 2、主要概念 下面让我们回…...

如何去阅读源码,我总结了18条心法
在聊如何去阅读源码之前,先来简单说一下为什么要去阅读源码,大致可分为以下几点原因:最直接的原因,就是面试需要,面试喜欢问源码,读完源码才可以跟面试官battle提升自己的编程水平,学习编程思想…...

排序:归并排序
一、归并 li[2,4,5,7,//1,3,6,8]#归并的前提是必须两部分排好序 def merge(li,low,mid,high):ilowjmid1ltmp[]while i<mid and j<high: #只要左右两边都有数if li[i]<li[j]:ltmp.append(li[i])i1else:ltmp.append(li[j])j1#while执行完,肯定有一部分没数…...

Allegro172版本线到铜皮不按照设定值避让的原因和解决办法
Allegro172版本线到铜皮不按照设定值避让的原因和解决办法 用Allegro做PCB设计的时候,有时会单独给某块铜皮附上线到铜皮额外再增加一个数值,如下图 在规则的基础上,额外再避让10mil 规则避让line到铜皮10.02mil 额外设置多避让10mil,避让的结果却是30.02mil,正确的是20.…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...