美文网首页
12-三层架构

12-三层架构

作者: D丝学编程 | 来源:发表于2021-04-19 10:27 被阅读0次

    三层架构将整个业务应用划分为:(1)界面UI层;(2)业务逻辑层;(3)数据访问层。

    对于复杂的系统分层可以让结构更加清晰,模块更加独立,便于维护。

    0048.PNG
    各层的任务:

    (1)数据访问层:负责数据库的操作。

    (2)业务逻辑层:实现功能模块的业务逻辑。

    (3)界面UI层:绘制界面,以及负责界面相关代码。

    (4)实体类:将数据库中的表转化为面向对象思想中的类。

    一、案例需求

    使用三层架构实现学生管理:


    0041.PNG

    (1)专业下拉框绑定专业表数据,网格控件绑定学生数据,并且点击"搜索"按钮可以多条件组合查询。

    (2)选中某一行,右键可以弹出"删除"菜单,点击"删除"菜单可以删除学生数据。

    (3)点击"新增"按钮,弹出新增窗体,在此窗体中完成学生的新增操作。


    0042.PNG

    (4)选中某一行,点击"编辑"按钮,弹出编辑窗体,在此窗体中完成数据的修改。


    0043.PNG
    备注:其中性别的单选框,以及爱好的多选框分别用两个Pannel容器包含。

    数据库准备:

    --专业
    create table ProfessionInfo
    (
        ProfessionID int primary key identity(1,1), --专业编号
        ProfessionName varchar(50) not null unique --专业名称
    )
    --学生
    create table StudentInfo
    (
        StuID varchar(20) primary key,  --学生学号
        StuName varchar(50) not null,       --学生姓名
        StuAge int not null check(StuAge > 0 and StuAge < 130), --学生年龄
        StuSex char(2) not null check(StuSex in('男','女')),  --学生性别
        StuHobby nvarchar(100), --爱好
        ProfessionID int not null references ProfessionInfo(ProfessionID), --所属专业编号
    )
    --添加专业信息
    insert into ProfessionInfo(ProfessionName) values('电子竞技')
    insert into ProfessionInfo(ProfessionName) values('软件开发')
    insert into ProfessionInfo(ProfessionName) values('医疗护理')
    --插入学生信息
    insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID)
    values('001','刘备',18,'男','',1)
    insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID)
    values('002','关羽',20,'男','',2)
    insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID)
    values('003','张飞',19,'男','',2)
    insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID)
    values('004','孙尚香',17,'女','',3)
    

    二、项目结构

    (1)创建一个空白解决方案。

    (2)在解决方案中创建类库项目MyEntity代表"实体类"。

    (3)在解决方案中创建类库项目MyDAL代表"数据访问层"。

    (4)在解决方案中创建类库项目MyBLL代表"业务逻辑层"。

    (5)在解决方案中创建Windows窗体应用程序MyUI代表"界面UI层"。


    0049.PNG

    三、实体类编写

    在MyEntity项目中添加两个实体类,实体类代码如下:

    ProfessionInfoEntity:

    public class ProfessionInfoEntity
    {
        public ProfessionInfoEntity()
        {
            this.ProfessionID = 0;
            this.ProfessionName = "";
        }
        public int ProfessionID { get; set; }  //专业编号
        public string ProfessionName { get; set; }//专业名称
    }
    

    StudentInfoEntiy:

    public class StudentInfoEntiy
    {
        public StudentInfoEntiy()
        {
            this.StuID = "";
            this.StuName = "";
            this.StuAge = 0;
            this.StuSex = "";
            this.StuHobby = "";
            this.ProfessionID = 0;
            this.ProfessionName = "";
        }
        public string StuID { get; set; }  //学生学号
        public string StuName { get; set; }  //学生姓名
        public int StuAge { get; set; }  //学生年龄
        public string StuSex { get; set; }  //学生性别
        public string StuHobby { get; set; }  //学生爱好
        public int ProfessionID { get; set; }  //学生所属专业编号
        public string ProfessionName { get; set; } //学生所属专业名称
    }
    

    四、数据访问层编写

    (1)由于数据访问层需要使用实体类,所以需要添加实体类的引用。

    即在MyDAL项目上右键-->添加-->引用-->项目,在项目中勾选MyEntity项目。

    (2)将之前封装好的DBHelper文件复制到MyDAL项目中,并通过添加现有项,将DBHelper加入项目。

    (3)在MyDAL项目中添加两个类,类代码如下:

    ProfessionInfoDAL:

    public class ProfessionInfoDAL
    {
        #region 新增
        public int Add(ProfessionInfoEntity entity)
        {
            string sql = "insert into ProfessionInfo(professionName) values(@professionName)";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("ProfessionName",entity.ProfessionName);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 删除
        public int Delete(int id)
        {
            string sql = "delete from ProfessionInfo where ProfessionID=@ProfessionID";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("ProfessionID", id);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 修改
        public int Update(ProfessionInfoEntity entity)
        {
            string sql = "update ProfessionInfo set professionName=@professionName where ProfessionID=@ProfessionID";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("professionName", entity.ProfessionName);
            DBHelper.SetParameter("ProfessionID", entity.ProfessionID);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 列表
        public List<ProfessionInfoEntity> List()
        {
            string sql = "select * from ProfessionInfo";
            DataTable dt = new DataTable();
            DBHelper.PrepareSql(sql);
            dt = DBHelper.ExecQuery();
            List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>();
            foreach (DataRow item in dt.Rows)
            {
                ProfessionInfoEntity entity = new ProfessionInfoEntity();
                entity.ProfessionID = int.Parse(item["ProfessionID"].ToString());
                entity.ProfessionName = item["ProfessionName"].ToString();
                list.Add(entity);
            }
            return list;
        }
        #endregion
    
        #region 详情
        public ProfessionInfoEntity Detail(int id)
        {
            string sql = "select * from ProfessionInfo where ProfessionID=@ProfessionID";
            DataTable dt = new DataTable();
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("ProfessionID", id);
            dt = DBHelper.ExecQuery();
            if (dt.Rows.Count == 0)
                return null;
            ProfessionInfoEntity entity = new ProfessionInfoEntity();
            entity.ProfessionID = int.Parse(dt.Rows[0]["ProfessionID"].ToString());
            entity.ProfessionName = dt.Rows[0]["ProfessionName"].ToString();
            return entity;
        }
        #endregion
    }
    

    StudentInfoDAL:

    public class StudentInfoDAL
    {
        #region 新增
        public int Add(StudentInfoEntiy entity)
        {
            string sql = "insert into StudentInfo(StuID,StuName,StuAge,StuSex,StuHobby,ProfessionID) values(@StuID,@StuName,@StuAge,@StuSex,@StuHobby,@ProfessionID)";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("StuID", entity.StuID);
            DBHelper.SetParameter("StuName", entity.StuName);
            DBHelper.SetParameter("StuAge", entity.StuAge);
            DBHelper.SetParameter("StuSex", entity.StuSex);
            DBHelper.SetParameter("StuHobby", entity.StuHobby);
            DBHelper.SetParameter("ProfessionID", entity.ProfessionID);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 删除
        public int Delete(string id)
        {
            string sql = "delete from StudentInfo where StuID=@StuID";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("StuID", id);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 修改
        public int Update(StudentInfoEntiy entity)
        {
            string sql = "update StudentInfo set StuName=@StuName,StuAge=@StuAge,StuSex=@StuSex,StuHobby=@StuHobby,ProfessionID=@ProfessionID where StuID=@StuID";
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("StuName", entity.StuName);
            DBHelper.SetParameter("StuAge", entity.StuAge);
            DBHelper.SetParameter("StuSex", entity.StuSex);
            DBHelper.SetParameter("StuHobby", entity.StuHobby);
            DBHelper.SetParameter("ProfessionID", entity.ProfessionID);
            DBHelper.SetParameter("StuID", entity.StuID);
            return DBHelper.ExecNonQuery();
        }
        #endregion
    
        #region 列表
        public List<StudentInfoEntiy> List()
        {
            string sql = "select * from StudentInfo";
            DataTable dt = new DataTable();
            DBHelper.PrepareSql(sql);
            dt = DBHelper.ExecQuery();
            List<StudentInfoEntiy> list = new List<StudentInfoEntiy>();
            foreach (DataRow item in dt.Rows)
            {
                StudentInfoEntiy entity = new StudentInfoEntiy();
                entity.StuID = item["StuID"].ToString();
                entity.StuName = item["StuName"].ToString();
                entity.StuAge = int.Parse(item["StuAge"].ToString());
                entity.StuSex = item["StuSex"].ToString();
                entity.StuHobby = item["StuHobby"].ToString();
                entity.ProfessionID = int.Parse(item["ProfessionID"].ToString());
                list.Add(entity);
            }
            return list;
        }
        #endregion
    
        #region 详情
        public StudentInfoEntiy Detail(string id)
        {
            string sql = "select * from StudentInfo where StuID=@StuID";
            DataTable dt = new DataTable();
            DBHelper.PrepareSql(sql);
            DBHelper.SetParameter("StuID", id);
            dt = DBHelper.ExecQuery();
            if (dt.Rows.Count == 0)
                return null;
            StudentInfoEntiy entity = new StudentInfoEntiy();
            entity.StuID = dt.Rows[0]["StuID"].ToString();
            entity.StuName = dt.Rows[0]["StuName"].ToString();
            entity.StuAge = int.Parse(dt.Rows[0]["StuAge"].ToString());
            entity.StuSex = dt.Rows[0]["StuSex"].ToString();
            entity.StuHobby = dt.Rows[0]["StuHobby"].ToString();
            entity.ProfessionID = int.Parse(dt.Rows[0]["ProfessionID"].ToString());
            return entity;
        }
        #endregion
    }
    

    五、业务逻辑层编写

    (1)由于业务逻辑层需要使用实体类,所以需要添加实体类的引用。

    即在MyBLL项目上右键-->添加-->引用-->项目,在项目中勾选MyEntity项目。

    (2)由于业务逻辑层需要调用数据访问层,所以需要添加数据访问层的引用。

    即在MyBLL项目上右键-->添加-->引用-->项目,在项目中勾选MyDAL项目。

    (3)在MyBLL项目中添加两个类,类代码如下:

    ProfessionInfoBLL:

    public class ProfessionInfoBLL
    {
        ProfessionInfoDAL dal = new ProfessionInfoDAL();
        #region 新增
        public int Add(ProfessionInfoEntity entity)
        {
            return dal.Add(entity);
        }
        #endregion
    
        #region 删除
        public int Delete(int id)
        {
            return dal.Delete(id);
        }
        #endregion
    
        #region 修改
        public int Update(ProfessionInfoEntity entity)
        {
            return dal.Update(entity);
        }
        #endregion
    
        #region 列表
        public List<ProfessionInfoEntity> List()
        {
            return dal.List();
        }
        #endregion
    
        #region 详情
        public ProfessionInfoEntity Detail(int id)
        {
            return dal.Detail(id);
        }
        #endregion
    }
    

    StudentInfoBLL:

    public class StudentInfoBLL
    {
        StudentInfoDAL dal = new StudentInfoDAL();
        #region 新增
        public int Add(StudentInfoEntiy entity)
        {
            return dal.Add(entity);
        }
        #endregion
    
        #region 删除
        public int Delete(string id)
        {
            return dal.Delete(id);
        }
        #endregion
    
        #region 修改
        public int Update(StudentInfoEntiy entity)
        {
            return dal.Update(entity);
        }
        #endregion
    
        #region 列表
        public List<StudentInfoEntiy> List()
        {
            return dal.List();
        }
        #endregion
    
        #region 详情
        public StudentInfoEntiy Detail(string id)
        {
            return dal.Detail(id);
        }
        #endregion
    }
    

    六、界面UI层代码编写

    (1)由于界面UI层需要使用实体类,所以需要添加实体类的引用。

    即在MyUI项目上右键-->添加-->引用-->项目,在项目中勾选MyEntity项目。

    (2)由于界面UI层需要调用业务逻辑层,所以需要添加业务逻辑层的引用。

    即在MyUI项目上右键-->添加-->引用-->项目,在项目中勾选MyBLL项目。

    查询窗体界面及代码:

    0041.PNG
    (1)由于查询学生需要多条件组合查询,所以给数据访问层和业务逻辑层添加条件搜索的方法。

    给数据访问层MyDAL中StudentInfoDAL类添加方法:

    #region 条件查询
    public List<StudentInfoEntiy> Search(StudentInfoEntiy searchObj)
    {
        string sql = "select * from StudentInfo inner join ProfessionInfo on StudentInfo.ProfessionID = ProfessionInfo.ProfessionID where 1 = 1";
        if (searchObj.ProfessionID != 0)
            sql += " and StudentInfo.ProfessionID = " + searchObj.ProfessionID;
        if (!searchObj.StuName.Equals(""))
            sql += " and StuName like '%" + searchObj.StuName + "%'";
        DataTable dt = new DataTable();
        DBHelper.PrepareSql(sql);
        dt = DBHelper.ExecQuery();
        List<StudentInfoEntiy> list = new List<StudentInfoEntiy>();
        foreach (DataRow item in dt.Rows)
        {
            StudentInfoEntiy entity = new StudentInfoEntiy();
            entity.StuID = item["StuID"].ToString();
            entity.StuName = item["StuName"].ToString();
            entity.StuAge = int.Parse(item["StuAge"].ToString());
            entity.StuSex = item["StuSex"].ToString();
            entity.StuHobby = item["StuHobby"].ToString();
            entity.ProfessionID = int.Parse(item["ProfessionID"].ToString());
            entity.ProfessionName = item["ProfessionName"].ToString();
            list.Add(entity);
        }
        return list;
    }
    #endregion
    

    给业务逻辑层MyBLL中StudentInfoBLL类添加方法:

    #region 条件查询
    public List<StudentInfoEntiy> Search(StudentInfoEntiy searchObj)
    {
        return dal.Search(searchObj);
    }
    #endregion
    

    (2)在此界面中多个功能需要调用业务逻辑层,定义两个业务逻辑层对象:

    ProfessionInfoBLL proBll = new ProfessionInfoBLL();
    StudentInfoBLL stuBll = new StudentInfoBLL();
    

    (3)查询窗体绑定专业信息、绑定学生信息以及搜索功能代码:

    #region 绑定下拉框
    private void BindPro()
    {
        List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>();
        list = proBll.List();
        list.Insert(0,new ProfessionInfoEntity { ProfessionID=0,ProfessionName="--请选择--"});
        this.cmbPro.DataSource = list;
        this.cmbPro.DisplayMember = "ProfessionName";
        this.cmbPro.ValueMember = "ProfessionID";
    }
    #endregion
    
    #region 绑定学生数据
    private void BindData()
    {
        StudentInfoEntiy searchObj = new StudentInfoEntiy();
        searchObj.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString());
        searchObj.StuName = this.txtName.Text;
        this.dataGridView1.AutoGenerateColumns = false;
        this.dataGridView1.DataSource = stuBll.Search(searchObj);
    }
    #endregion
    
    #region 窗体加载
    private void FrmSelect_Load(object sender, EventArgs e)
    {
        BindPro();
        BindData();
    }
    #endregion
    
    #region 搜索按钮
    private void btSearch_Click(object sender, EventArgs e)
    {
        BindData();
    }
    #endregion
    

    (4)删除菜单代码:

    private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        //添加是否确定删除的对话框
        DialogResult result = MessageBox.Show("确定要删除数据吗,删除之后无法恢复!", "提示框",
            MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        if (result == DialogResult.Cancel)
            return;
        string stuid = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
        if(stuBll.Delete(stuid) == 1)
            MessageBox.Show("删除成功!");
        else
            MessageBox.Show("删除失败!");
        BindData();
    }
    

    新增窗体界面及代码:

    0042.PNG
    ProfessionInfoBLL proBll = new ProfessionInfoBLL();
    StudentInfoBLL stuBll = new StudentInfoBLL();
    #region 绑定下拉框
    private void BindPro()
    {
        List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>();
        list = proBll.List();
        list.Insert(0, new ProfessionInfoEntity { ProfessionID = 0, ProfessionName = "--请选择--" });
        this.cmbPro.DataSource = list;
        this.cmbPro.DisplayMember = "ProfessionName";
        this.cmbPro.ValueMember = "ProfessionID";
    }
    #endregion
    private void FrmAdd_Load(object sender, EventArgs e)
    {
        BindPro();
    }
    
    private void btAdd_Click(object sender, EventArgs e)
    {
        //性别处理
        string sex = "";
        if (this.rbBoy.Checked == true) sex = this.rbBoy.Text;
        if (this.rbGirl.Checked == true) sex = this.rbGirl.Text;
        //爱好处理
        string hobby = "";
        foreach (CheckBox ck in this.panel2.Controls)
        {
            if (ck.Checked == true)
            {
                if (!hobby.Equals(""))
                    hobby += ",";
                hobby += ck.Text;
            }
        }
        StudentInfoEntiy entity = new StudentInfoEntiy();
        entity.StuID = this.txtId.Text;
        entity.StuName = this.txtName.Text;
        entity.StuAge = int.Parse(this.txtAge.Text);
        entity.StuSex = sex;
        entity.StuHobby = hobby;
        entity.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString());
        if (stuBll.Add(entity) == 1)
            MessageBox.Show("新增成功!");
        else
            MessageBox.Show("新增失败!");
        this.Close();
    }
    

    编辑修改窗体界面及代码:

    0043.PNG
    public string StuID { get; set; } //学生编号
    ProfessionInfoBLL proBll = new ProfessionInfoBLL();
    StudentInfoBLL stuBll = new StudentInfoBLL();
    #region 绑定下拉框
    private void BindPro()
    {
        List<ProfessionInfoEntity> list = new List<ProfessionInfoEntity>();
        list = proBll.List();
        list.Insert(0, new ProfessionInfoEntity { ProfessionID = 0, ProfessionName = "--请选择--" });
        this.cmbPro.DataSource = list;
        this.cmbPro.DisplayMember = "ProfessionName";
        this.cmbPro.ValueMember = "ProfessionID";
    }
    #endregion
    
    #region 绑定详情
    private void BindDetail()
    {
        StudentInfoEntiy entity = new StudentInfoEntiy();
        entity = stuBll.Detail(this.StuID);
        this.txtId.Text = entity.StuID;
        this.txtName.Text = entity.StuName;
        this.txtAge.Text = entity.StuAge.ToString();
        this.cmbPro.SelectedValue = entity.ProfessionID;
        //性别处理
        if (entity.StuSex.Equals("男"))
            this.rbBoy.Checked = true;
        else
            this.rbGirl.Checked = true;
        //爱好处理
        string[] arrHobby = entity.StuHobby.Split(',');
        foreach (string hobby in arrHobby)
        {
            foreach (CheckBox ck in this.panel2.Controls)
            {
                if (ck.Text.Equals(hobby))
                    ck.Checked = true;
            }
        }
    }
    #endregion
    
    private void FrmEdit_Load(object sender, EventArgs e)
    {
        BindPro();
        BindDetail();
    }
    
    private void btUpdate_Click(object sender, EventArgs e)
    {
        //性别处理
        string sex = "";
        if (this.rbBoy.Checked == true) sex = this.rbBoy.Text;
        if (this.rbGirl.Checked == true) sex = this.rbGirl.Text;
        //爱好处理
        string hobby = "";
        foreach (CheckBox ck in this.panel2.Controls)
        {
            if (ck.Checked == true)
            {
                if (!hobby.Equals(""))
                    hobby += ",";
                hobby += ck.Text;
            }
        }
        StudentInfoEntiy entity = new StudentInfoEntiy();
        entity.StuID = this.txtId.Text;
        entity.StuName = this.txtName.Text;
        entity.StuAge = int.Parse(this.txtAge.Text);
        entity.StuSex = sex;
        entity.StuHobby = hobby;
        entity.ProfessionID = int.Parse(this.cmbPro.SelectedValue.ToString());
        if (stuBll.Update(entity) == 1)
            MessageBox.Show("修改成功!");
        else
            MessageBox.Show("修改失败!");
        this.Close();
    }
    
    

    查询窗体中"新增"和"编辑"按钮代码:

    private void btAdd_Click(object sender, EventArgs e)
    {
        FrmAdd frm = new FrmAdd();
        frm.Show();
    }
    
    private void btEdit_Click(object sender, EventArgs e)
    {
        string stuid = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
        FrmEdit frm = new FrmEdit();
        frm.StuID = stuid;
        frm.Show();
    }
    

    相关文章

      网友评论

          本文标题:12-三层架构

          本文链接:https://www.haomeiwen.com/subject/chhzkltx.html