数据库操作类《SqlHelper》

 一.背景

在看了一本书叫《Visual Studio 2010(C#Windows数据库项目开发》后,觉得很多编程技术需要积累,因为一个简单的项目里包含的技术太多了,容易忘记。每次需要用到某个技术时,就免不了查阅资料,然后整理一堆操作后,发现浪费很多时间。

现在呢,由于这个书没有对数据库操作做一个公共类设计,每次访问数据库的时候都会造成冗余代码。为了解决这个问题,我查阅了很多网上资源,当然里面也有一丢丢自己的思考,总结成一个编程技术学习日记,以便日后自己翻阅。

二.设计

数据库的操作主要包括:查询,添加,删减,更新。目前只讨论“增删查改”的实现,数据库中的存储过程、视图、函数、触发器等知识点这里就不说了,后面在实现这个学生选课系统项目时再讨论吧。

0. 首先定义一个用于初始化SqlCommand对象的方法:

//初始化SqlCommand对象
public static void InitializeCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] paras)
{
    if(conn.State != ConnectionState.Open())
        conn.Open();
    cmd.Connection = conn;
    cmd.CommandText = cmdText;
    if(trans != null)
        cmd.Transaction = trans;
    cmd.CommandType = cmdType;
    if(paras != null)
        foreach( SqlParameter item in paras)
        {
            cmd.Parameters.Add(item);
        }
}

 1. 查询

查询返回一个数据集DataSet或者数据表DataTable,通用型的数据库查询方法:

//查询数据,返回相应的数据表
public static DataTable GetDataTable(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras)
{
    SqlCommand cmd = new SqlCommand();
    using(SqlConnection conn = new SqlConnection(connString))
    {
        InitializeCommand(cmd,conn,null,cmdType,cmdText,paras);
        using(SqlDataAdapter adapter = new SqlDataAdapter(cmd))
        {
            DataTable dt = new DataTable();
            adapter.Fill(dt);
            cmd.Parameters.Clear();
            return dt;
        }
    }
}

 查询返回第一列第一行的数据,即返回单个数据的查询方法:

//查询单个数据,返回第一列第一行的数据
public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras)
{
    SqlCommand cmd = new SqlCommand();
    using(SqlConnection conn = new SqlConnection(connString)
    {
        InitializeCommand(cmd,conn,null,cmdType,cmdText,paras);
        object obj = cmd.ExecuteScalar();
        cmd.Parameters.Clear();
        return obj;
    }
}

 查询返回一个SqlDataReader数据读取器,当这个数据读取器在读取数据库数据的时候一直和数据库保持连接,并且一行一行地读取,此查询的方法:

//查询返回SqlDataReader数据读取器,用于一行一行地读取数据库数据
public static SqlDataReader ExecuteReader(string connString, CommandType cmdType,string cmdText,params SqlParameter[] paras)
{
    SqlCommand cmd = new SqlCommand();
    SqlConnection conn = new SqlConnection(connString);
    try
    {
        InitializeCommand(cmd,conn,null,cmdType,cmdText,paras);
        SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        cmd.Parameters.Clear();
        return reader;
    }
    catch
    {
        conn.Close();
        throw;
    }
}

 2. 添加、删除、更新

数据库的增删改可以通过传递不同的SQL命令,以一种通用型的方法来实现增删改。具体的方法为:

//针对数据库的增删改,设计一个通用型的方法,返回值为受影响的行数
public static int ExecuteNonQuery(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras)
{
    SqlCommand cmd = new SqlCommand();
    using(SqlConnection conn = new SqlConnection(connString))
    {
        InitializeCommand(cmd,conn,null,cmdType,cmdText,paras);
        int rows = cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        retuen rows;
    }
}

 三.实践

 写好了数据库操作类SqlHelper后,运用实际例子来验证一下。

1.打开数据库,创建数据库命名为XK,新建一个tb_Departdent表,预先插入三行数据,用于增删查改操作。

create database XK
create table tb_Department
(
    DeptNO int not null primary key identity(1,1),
    DeptName nvarchar(32) null
)
insert into tb_Department(DeptName) values(N'计算机应用工程系')
insert into tb_Department(DeptName) values(N'建筑工程系')
insert into tb_Department(DeptName) values(N'旅游系')

2.打开VS,新建一个窗体项目,将窗体UI设计成如下图所示。(toolstripdatagridview控件的设置我这里就不说了,很简单,不知道可以在园里找找)

窗体在加载的时候将从数据库中读取tb_Department表中的全部数据,并显示在datagridview控件中。加载事件处理程序如下:

        private void LoadData()
        {
            //首先定义用于查询的SQL脚本
            string cmdText = @"select DeptNO,DeptName from tb_Department";
            //使用SqlHelper操作类来读取表数据
            //定义一个用于存储读取过来的表数据DataTable对象
            DataTable dt = SqlHelper.GetDataTable(SqlHelper.ConnString, CommandType.Text, cmdText);
            this.dgvDept.DataSource = dt;
        }
        //窗体加载时导入表数据
        private void DeptForm_Load(object sender, EventArgs e)
        {
            LoadData();
        }

加载后的效果,groupbox控件设置为不可用。

3.增加、删除、修改的方法实现。

        /// <summary>
        /// 插入数据
        /// </summary>
        private void InsertData()
        {
            //判断系部名称是否为空
            if (string.IsNullOrEmpty(this.txtDeptName.Text.Trim()))
            {
                MessageBox.Show("系部名称不能为空!");
                return;
            }
            //定义插入数据的Sql脚本
            string cmdText = @"insert into tb_Department(DeptName) values(@DeptName)";
            //SQL脚本参数设置
            SqlParameter[] parameters =
            {
                //new SqlParameter("@DeptNO",(object)this.lbDeptNO.Text),
                new SqlParameter("@DeptName",(object)this.txtDeptName.Text.Trim())
            };
            //执行插入,并返回受影响的行数
            int rows = SqlHelper.ExecuteNonQuery(SqlHelper.ConnString, CommandType.Text, cmdText, parameters);
            //判断是否插入成功,并提示
            if (rows > 0)
            {
                //更新datagridview控件的数据
                LoadData();
                MessageBox.Show("插入成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("插入失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        /// <summary>
        /// 删除数据
        /// </summary>
        private void DeleteData()
        {
            //确认是否删除
            if (MessageBox.Show("确定要删除该行数据吗?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                //定义删除相应数据的SQL脚本
                string cmdText = @"delete from tb_Department where DeptNO=@DeptNO";
                //定义SQL参数
                SqlParameter[] parameters =
                {
                    new SqlParameter("@DeptNO",(object)this.lbDeptNO.Text)
                };
                //接受返回的受影响的行数
                int rows = SqlHelper.ExecuteNonQuery(SqlHelper.ConnString, CommandType.Text, cmdText, parameters);
                //判断是否插入成功,并提示
                if (rows > 0)
                {
                    //更新datagridview控件的数据
                    LoadData();
                    MessageBox.Show("删除成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("删除失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        private void UpdateData()
        {
            //判断系部名称是否为空
            if (string.IsNullOrEmpty(this.txtDeptName.Text.Trim()))
            {
                MessageBox.Show("系部名称不能为空!");
                return;
            }
            //确认是否修改
            if (MessageBox.Show("确定要修改该行数据吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                //定义删除相应数据的SQL脚本
                string cmdText = @"update tb_Department set DeptName=@DeptName where DeptNO=@DeptNO";
                //定义SQL参数
                SqlParameter[] parameters =
                {
                    new SqlParameter("@DeptNO",(object)this.lbDeptNO.Text),
                    new SqlParameter("@DeptName",(object)this.txtDeptName.Text)
                };
                //接受返回的受影响的行数
                int rows = SqlHelper.ExecuteNonQuery(SqlHelper.ConnString, CommandType.Text, cmdText, parameters);
                //判断是否插入成功,并提示
                if (rows > 0)
                {
                    //更新datagridview控件的数据
                    LoadData();
                    MessageBox.Show("修改成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("修改失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

4.为“提交”按钮编写点击处理事件之前,我们需要设计一个CmdType枚举来标识点击提交按钮执行的是新增,删除或者更新操作。

    /// <summary>
    /// 用于标识命令操作的类型
    /// </summary>
    public enum CmdType
    {
        Insert,
        Delete,
        Update
    }

5.分别为窗体的增加,删除,修改和提交按钮编写点击处理程序。

        /// <summary>
        /// 用于标识SQL命令操作的类型
        /// </summary>
        private CmdType cmdType { get; set; }

private void tsbInsert_Click(object sender, EventArgs e) { cmdType = CmdType.Insert; //将gbDept控件设置可用,textbox控件设为可用,并将Text属性清空 this.gbDept.Enabled = true; this.txtDeptName.Enabled = true; this.txtDeptName.Text = string.Empty; this.lbDeptNO.Text = "DeptNO";
} private void tsbDelete_Click(object sender, EventArgs e) { //将sql命令类型设置为删除 cmdType = CmdType.Delete; //启用groupbox控件,textbox设置不可用 this.gbDept.Enabled = true; this.txtDeptName.Enabled = false; //获取要删除的行数据,并赋值给相应控件 this.lbDeptNO.Text = dgvDept.SelectedRows[0].Cells["DeptNO"].Value.ToString(); this.txtDeptName.Text = dgvDept.SelectedRows[0].Cells["DeptName"].Value.ToString(); } private void tsbUpdate_Click(object sender, EventArgs e) { //将sql命令类型设置为删除 cmdType = CmdType.Update; //启用groupbox控件,textbox控件设置为可用 this.gbDept.Enabled = true; this.txtDeptName.Enabled = true; //获取要删除的行数据,并赋值给相应控件 this.lbDeptNO.Text = dgvDept.SelectedRows[0].Cells["DeptNO"].Value.ToString(); this.txtDeptName.Text = dgvDept.SelectedRows[0].Cells["DeptName"].Value.ToString(); } private void btnOK_Click(object sender, EventArgs e) { //执行增删改操作 switch (cmdType) { case CmdType.Insert: InsertData(); break; case CmdType.Delete: DeleteData(); break; case CmdType.Update: UpdateData(); break; } }

 四.结果

 应用程序的UI和编码工作做完之后,当然就是调试各项功能了。

1.增加功能:点击增加按钮,在系部名称输入要插入的系部:“哈哈系”,然后点击提交按钮,数据被插入到数据库中了,为了后续操作,再插入“嘿嘿系”和“嘟嘟系”。

2.删除功能:选择要删除的行数据(将“嘿嘿系”删除),点击删除按钮,窗体下方会显示要删除的行数据信息,点击提交按钮后会提示用户是否确定要删除数据,点击“是”后显示删除成功,datagridview控件中确实没有“嘿嘿系”了。

3.修改功能:选择要修改的行数据,窗体下方会显示相应的信息,textbox控件为可编辑,我们把“哈哈系”改成“光电系”,点击提交按钮,确认修改,datagridview控件中“哈哈系”变成了“光电系”,修改成功。

 四.总结

本文主要针对数据库操作类SqlHelper的产生背景,设计过程,实践运用以及调试结果进行讲解,虽然描述的很粗糙,但是也算是一种数据库操作技术的积累。

实践运用遇到的主要问题:

  • 新插入数据行中的自增长主键,由数据库自动增加,不受人为控制,比如在讲解增加功能的时候,新插入的行时,数据库会自动给自增长字段赋一个值,而这个值不是我们希望的。比如一个表中有Id,Name字段,Id为自增长主键,原有表中有1-a,2-b,3-c三行数据,现在删除3-c这一行的数据,然后在插入c数据库会自动给Id赋值为4,即:4-c,而不是我们想要的3-c

如何在插入新数据时,自动获得缺失的自增值来赋值给Id呢?这个问题我会在下一篇博客中解决。

 

posted on 2018-08-05 01:42  yellowstronger  阅读(3776)  评论(1编辑  收藏  举报

导航