【C#桌面客户端系列学习-14】SQLite数据库之增删改查完整示例

目录

一、前言

二、效果图

三、数据库设计

四、完整示例

1、测试数据库连接状态

2、添加功能

3、查询功能

4、修改功能

5、删除功能

6、批量导入Excel


一、前言

本篇文字以示例的形式介绍完整的数据库基础操作------增删改查。使用已经封装好的数据库工具类。

数据库类型:SQLite

语言:C#

形式:客户端

使用工具类:下面所有示例代码中的SqliteHelper使用的都是封装好的此工具类!!! 【C#桌面客户端系列学习-12】封装SQLite数据库基础操作工具类(CURD)-CSDN博客

二、效果图

主要功能

  • 测试数据库连接
  • 添加信息
  • 查询列表
  • 修改信息
  • 删除条目
  • 批量导入Excel

三、数据库设计

数据库比较简单,只有一个user表。

四、完整示例

1、测试数据库连接状态

数据库连接配置参看:【C#桌面客户端系列学习-10】连接SQLite数据库-CSDN博客

点击"测试连接"按钮,显示SQLite数据库连接状态。

cs 复制代码
private void btnTestConn_Click(object sender, EventArgs e)
{
    if (SqliteHelper.TestConnection())
    {
        lblStatus.Text = "✅ 数据库连接成功!";
        lblStatus.ForeColor = System.Drawing.Color.Green;
    }
    else
    {
        lblStatus.Text = "❌ 数据库连接失败,请检查连接字符串!";
        lblStatus.ForeColor = System.Drawing.Color.Red;
    }
}

2、添加功能

字段:

|--------------|-------------|-----------|
| 用户名:UserName | 密码:PassWord | 状态:status |

cs 复制代码
private void btnAdd_Click(object sender, EventArgs e)
{

    // ================== 1. 接收并校验表单数据 ==================
    //接收前端传过来的值
    string username = this.UserName.Text;
    string password = this.PassWord.Text;
    string status = this.status.Text;
    if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
    {
        MessageBox.Show("用户名和密码不能为空!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    // 哈希密码
    string passwordHash = BCrypt.Net.BCrypt.HashPassword(password);

    try
    {
        // 先检查用户是否已存在
        string checkSql = "select count(*) from user where username = @username";
        object result = SqliteHelper.ExecuteScalar(checkSql, new SQLiteParameter("@username", username));
        int count = Convert.ToInt32(result);
        if (count > 0) {
            MessageBox.Show("该用户已存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
        string sql = "INSERT INTO user (username, password, status) VALUES (@username, @password, @status)";
        SQLiteParameter[] insertParams = { 
            new SQLiteParameter("@username", username),
            new SQLiteParameter("@password", passwordHash),
            new SQLiteParameter("@status", status)
        };

        int res = SqliteHelper.ExecuteNonQuery(sql, insertParams);
        if (res > 0)
        {
            // 操作成功
            MessageBox.Show("操作成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

            // 可选:清空输入框
            this.UserName.Text = "";
            this.PassWord.Text = "";
            this.status.Text = "";
        }
        else {
            // 操作失败
            MessageBox.Show("操作失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
    catch (Exception ex)
    {

        MessageBox.Show($"操作失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

业务逻辑

Step1:接收前端传过来的值

Step2:校验非空

Step3:密码使用哈希密码加密(需要安装BCrypt.Net-Next程序包,参考:【C#桌面客户端系列学习-5】注册/登录-CSDN博客)

Step4:检查新添加的数据是否已经存在

Step5:插入数据库

3、查询功能

cs 复制代码
private void btnSearch_Click(object sender, EventArgs e)
{
    string username = this.txtSearch.Text;
    try
    {
        string sql = "SELECT id, username, CASE status WHEN 1 THEN '开启'  WHEN 2 THEN '关闭' ELSE '未知' END AS status FROM user WHERE username LIKE @username ORDER BY ID ASC";
        SQLiteParameter[] parameters = { new SQLiteParameter("@username", "%" + username + "%") };
        
        DataTable dt = SqliteHelper.ExecuteDataTable(sql, parameters);
        dgvUsers.DataSource = dt;

        // 设置标题
        if (dgvUsers.Columns.Contains("id"))
            dgvUsers.Columns["id"].HeaderText = "编号";
        if (dgvUsers.Columns.Contains("username"))
            dgvUsers.Columns["username"].HeaderText = "用户名";
        if (dgvUsers.Columns.Contains("status"))
            dgvUsers.Columns["status"].HeaderText = "状态";

        // 添加修改/删除列
        // 先移除旧的按钮列,避免重复添加
        if (dgvUsers.Columns.Contains("colEdit"))
            dgvUsers.Columns.Remove("colEdit");
        if (dgvUsers.Columns.Contains("colDelete"))
            dgvUsers.Columns.Remove("colDelete");

        // 修改按钮列
        DataGridViewButtonColumn btnEdit = new DataGridViewButtonColumn();
        btnEdit.Name = "colEdit";
        btnEdit.HeaderText = "操作";
        btnEdit.Text = "修改";
        btnEdit.UseColumnTextForButtonValue = true;
        btnEdit.Width = 60;
        dgvUsers.Columns.Add(btnEdit);

        // 删除按钮列
        DataGridViewButtonColumn btnDelete = new DataGridViewButtonColumn();
        btnDelete.Name = "colDelete";
        btnDelete.HeaderText = "操作";
        btnDelete.Text = "删除";
        btnDelete.UseColumnTextForButtonValue = true;
        btnDelete.Width = 60;
        dgvUsers.Columns.Add(btnDelete);
    }
    catch (Exception ex)
    {

        MessageBox.Show("查询失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    }

}

业务逻辑

表格名称:dgvUsers,搜索框名称:txtSearch

Step1:接收前端传过来的查询关键词txtSearch

Step2:构造sql语句,查询数据库

Step3:设置表格属性(标题、修改、删除),表格属性也可以在设计器里设置(可参看【C#桌面客户端系列学习-8】数据修改、数据删除-CSDN博客)

4、修改功能

Step1:添加"修改/删除"按钮事件

cs 复制代码
private void dgvUsers_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    // 忽略表头行
    if (e.RowIndex < 0) return;

    // 获取当前行的 id
    int id = Convert.ToInt32(dgvUsers.Rows[e.RowIndex].Cells["id"].Value);

    // 判断点的是哪一列
    string colName = dgvUsers.Columns[e.ColumnIndex].Name;

    if (colName == "colEdit")
    {
        // 打开修改窗口,传入 id
        LiteEditUserForm form = new LiteEditUserForm(id);
        if (form.ShowDialog() == DialogResult.OK)
        {
            LoadUserData();  // 修改成功后刷新表格
        }
    }
    else if (colName == "colDelete")
    {
        // 确认删除
        DialogResult result = MessageBox.Show("确定要删除这条用户吗?", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

        if (result == DialogResult.Yes)
        {
            string sql = "DELETE FROM user WHERE id = @id";
            SqliteHelper.ExecuteNonQuery(sql, new SQLiteParameter("@id", id));

            MessageBox.Show("删除成功!");
            LoadUserData();  // 刷新表格
        }
    }
}

在.cs文件里添加上面的按钮事件,然后在设计器->选中表格->属性->事件(闪电图表)->找到CellContentClick->选择上面刚添加的事件dgvUsers_CellContentClick。

这个方法是用来判断当前点击的按钮类型,根据点击的按钮类型调用不同的方法(修改/删除)。

注意:按钮类型是根据colName判断的,colName名称要和输出表格时的btnEdit.Name名称一致

Step2:创建修改表单窗体

创建一个名为"LiteEditUserForm.cs"的修改表单窗体。

cs 复制代码
public partial class LiteEditUserForm : Form
{
    // 保存传进来的id
    private int _id;

    public LiteEditUserForm(int id)
    {
        InitializeComponent();
        _id = id;   // 先存起来,Load里用
    }

    // 留一个无参构造!!!!防止设计器打开窗体时报错
    public LiteEditUserForm()
    {
        InitializeComponent();
    }


    /// <summary>
    /// 清空数据
    /// </summary>
    private void button1_Click(object sender, EventArgs e)
    {
        UserName.Clear();
    }

    /// <summary>
    /// 加载数据并回填
    /// </summary>
    private void formEdit_Load(object sender, EventArgs e) {

        if (_id <= 0) return;

        try
        {
            //查询数据
            string sql = "SELECT * FROM user WHERE id = @id";
            DataRow row = SqliteHelper.ExecuteDataRow(sql, new SQLiteParameter("@id", _id));

            if (row == null) {
                MessageBox.Show("记录不存在");
                this.Close();
                return;
            }

            // 数据回填
            this.UserName.Text = row["username"].ToString();
            int status = Convert.ToInt32(row["status"]);
            status1.Checked = (status == 1);
            status2.Checked = (status == 2);
        }
        catch (Exception ex)
        {

            MessageBox.Show($"数据加载失败:{ex.Message}");
        }

    }

    /// <summary>
    /// 提交数据
    /// </summary>
    private void btnSave_Click(object sender, EventArgs e)
    {
        string username = this.UserName.Text;
        int status = 0;
        if (status1.Checked)
        {
            status = 1;
        }
        else if (status2.Checked)
        {
            status = 2;
        }
        else {
            MessageBox.Show("请选择状态!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        // 更新数据
        string sql = "UPDATE user SET username = @username, status = @status WHERE id = @id";

        SQLiteParameter[] ps = { 
            new SQLiteParameter("@username", username),
            new SQLiteParameter("@status", status),
            new SQLiteParameter("@id", _id)
        };
        int rows = SqliteHelper.ExecuteNonQuery(sql, ps);
        if (rows > 0)
        {
            MessageBox.Show("操作成功");
            this.DialogResult = DialogResult.OK;    // 通知父窗体
            this.Close();
        }
        else
        {
            MessageBox.Show("操作失败");
        }

    }
}

业务逻辑

Step1:添加"修改/删除"按钮事件,在此事件中判断点击的按钮类型,根据按钮类型处理不同的业务

Step2:创建修改表单窗体

Step3:修改窗体里,接收传过来的id

Step4:构造一个无参数的函数LiteEditUserForm,防止设计器打开窗体时报错

Step5:根据接收过来的Id,去查询数据库,将查出的数据回填到前端控件

Step5:再进行提交数据操作(接收修改好的数据,提交数据库修改)

5、删除功能

在刚添加的dgvUsers_CellContentClick方法中,如果按钮事件是colDelete,进行删除操作。

注意:按钮类型是根据colName判断的,colName名称要和输出表格时的btnEdit.Name名称一致

cs 复制代码
private void dgvUsers_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    // 忽略表头行
    if (e.RowIndex < 0) return;

    // 获取当前行的 id
    int id = Convert.ToInt32(dgvUsers.Rows[e.RowIndex].Cells["id"].Value);

    // 判断点的是哪一列
    string colName = dgvUsers.Columns[e.ColumnIndex].Name;

    if (colName == "colEdit")
    {
        // 打开修改窗口,传入 id
        LiteEditUserForm form = new LiteEditUserForm(id);
        if (form.ShowDialog() == DialogResult.OK)
        {
            LoadUserData();  // 修改成功后刷新表格
        }
    }
    else if (colName == "colDelete")
    {
        // 确认删除
        DialogResult result = MessageBox.Show("确定要删除这条用户吗?", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

        if (result == DialogResult.Yes)
        {
            string sql = "DELETE FROM user WHERE id = @id";
            SqliteHelper.ExecuteNonQuery(sql, new SQLiteParameter("@id", id));

            MessageBox.Show("删除成功!");
            LoadUserData();  // 刷新表格
        }
    }
}

6、批量导入Excel

参看:【C#桌面客户端系列学习-13】批量导入Excel数据到SQLite数据库-CSDN博客

相关推荐
她的男孩1 小时前
JAR 全对仍 checksum mismatch:Forge Admin 把 Flyway 从 filesystem 改成 classpath
java·数据库·spring boot
小马不起床1 小时前
Django 后端实战指南_16:动作分类、动作库、动作收藏查询接口
数据库·python·django
ycydynq1 小时前
django搜索功能
数据库·python·django
呆萌很1 小时前
DISTINCT 和 GROUP BY 核心区别
数据库·sql
小蒜学长1 小时前
基于数据挖掘的京东商城商品推荐系统设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·推荐系统·个性化推荐
小小AK1 小时前
金蝶其他入库到MES送检签收:库存同步策略实战教程
数据库·制造
LuminousCPP1 小时前
数据库学习笔记(二):MySQL 基础操作入门|在 CentOS Stream 10 上连接、建库与建表
数据库·经验分享·笔记·学习·mysql·centos
运维小斌1 小时前
麒麟 V10 ARM64 离线部署 OceanBase:8 步实施手册
linux·数据库·oceanbase·麒麟
Gh0st_Lx2 小时前
【1】MySQL MVCC 与隔离级别
数据库·mysql·mvcc