三层结构总结

三层简介:

何时使用:

当业务复杂,把数据存储到相应的数据库或者独立的数据存储介质,把数据库访问层脱离业务独立存在,业务脱离UI单独存在。

DAL(数据访问层):访问所有的数据源。

作用:一,从数据源加载数据(Select)二,向数据源写入数据(Insert/Update)三,从数据源删除数据(Delete)(除了这些基本的数据访问,其他一概不管)

BLL(业务逻辑层):

作用:一,从DAL中获取数据,以供UI显示用。二,从UI中获取用户指令和数据,执行业务逻辑。三,从UI中获取用户指令和数据,通过DAL写入数据源。(负责处理业务逻辑。通过获取UI传来的操作指令,决定执行业务逻辑,在需要访问数据源的时候直接交给DAL处理。处理完成后,返回必要数据给UI。)

BLL职责机制:

一:UI--->BLL--->DAL--->BLL--->UI:UI提出请求并搜集一定的用户数据传给BLL,BLL处理不了需要访问数据源,把请求转给DAL,DAL经过数据源访问加工,转给BLL,BLL得到想要的结果,把结果返回给UI。

二:UI--->BLL--->UI:UI给BLL,BLL能处理经过加工处理直接给UI。

UI(显示层):用户至上,兼顾简洁

作用:一,向用户展现特定业务数据。二,采集用户的输入信息和操作。(只负责显示和采集用户操作,不包含任何的业务相关的逻辑处理。)

各个层之间的引用关系:UI--->BLL--->DAL

DAL所在程序集不引用BLL和UI。

BLL需要引用DAL

UI直接引用BLL,可能会间接引用DAL

实际演练:

 

LoginUI:界面,只负责显示和采集用户操作,完成数据输入与输出。

F o r m 1 . c s:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LoginUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();//初始化FORM
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {//显示层不能和数据源直接打交道,所以需要业务逻辑层来支持。
            //IDbConnection conn = new SqlConnection();
            //IDbCommand cmd = conn.CreateCommand();
            //cmd.CommandText = "Select UserName From USERS WHERE ...";
            //cmd.ExecuteReader();
            //Trim函数移除两侧空白
            string userName = txtUserName.Text.Trim();
            string password = txtPassword.Text;
            //转至.BLL(业务逻辑层) UI提出请求并搜集一定的用户数据传给BLL(业务逻辑层)
            Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
            //Model是用来传输数据的业务数据模型 //BLL得到想要的结果,把结果返回给UI。
            Login.Model.UserInfo user= mgr.UserLogin(userName, password);

            MessageBox.Show("登录用户:" +user.UserName);
        }
    }
}

P r o g r a m . c s :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LoginUI
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

LoginBLL:处理业务逻辑,调用DAL处理数据,实现从UI到DAL的数据传输,在一定程度上解耦,解除客户端和数据库的耦合。

LoginManager.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Login.BLL
{
    public class LoginManager
    {//User数据模型。 
        public Login.Model.UserInfo UserLogin(string userName,string password)
        { 
            Login.DAL.UserDAO uDao = new Login.DAL.UserDAO(); 
            Login.Model.UserInfo user= uDao.SelectUser(userName, password);
            //DAL经过数据源访问加工,转给BLL.证明数据库有User 
            if (user!=null)//login successfully(登录成功)加10分
            {
                Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
                sDao.UpdateScore(userName, 10);//BLL转到DAL进行加分
                return user;
            }
            else
            {//自己写的抛出错误的原因
                throw new Exception("登录失败");
                //MessageBox.Show( user.UserName + "登录失败:");
            }
        }
    }
}

LoginDAL:与具体的数据库打交道,对数据进行插入和读取。

DbUtil.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Login.DAL
{
    class DbUtil
    {
        public static string ConnString = @"Server=DESKTOP-GFAMGHI;Database=Login;User ID =sa;Password=123456";
    }
}

ScoreDAO.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace Login.DAL
{
   public class ScoreDAO
    {
        public void UpdateScore(string userName,int value)
        { 
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//创建连接,数据库连接对象conn
            {
                SqlCommand cmd = conn.CreateCommand();//创建命令
                //往表中插入数据.
                cmd.CommandText = @"INSERT INTO SCORES(UserName,Score)Values(@UserName,@Score)";//设置操作语句
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));//添加参数 
                cmd.Parameters.Add(new SqlParameter("@Score", value));//设置参数值

                conn.Open();//打开链接
                cmd.ExecuteNonQuery(); //执行命令,增删改操作。
            }
        }
    }
}

UserDAO.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Login.DAL
{
  public class UserDAO
    {//BLL处理不了,把请求转给DAL,DAL访问数据源.
        public Login.Model.UserInfo SelectUser(string userName,string password)
        {
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//创建连接
            {
                SqlCommand cmd = conn.CreateCommand();//创建命令
                cmd.CommandText = @"SELECT ID,UserName,Password,Email
FROM USERS WHERE UserName=@UserName AND Password = @Password";//设置操作语句
                cmd.CommandType = CommandType.Text;//CommandType是SqlCommand对象的一个属性,
                //用于指定执行动作的形式,它告诉.net接下来执行的是一个文本(text)
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));//添加参数
                cmd.Parameters.Add(new SqlParameter("@Password", password));//设置参数值

                conn.Open();//打开连接,这里是基于链接的数据库访问模式。
                SqlDataReader reader = cmd.ExecuteReader(); //执行命令,增删改操作//通过SqlDataReader类依次读取。
                Login.Model.UserInfo user = null;  
                //读取数据
                while (reader.Read())//遍历所有记录
                {
                    if (user == null)
                    {
                        user = new Login.Model.UserInfo();
                    }
                    user.ID = reader.GetInt32(0);//取那一列第一个数
                    user.UserName = reader.GetString(1);//按照string类型读取
                    user.Password = reader.GetString(2); 
                    if (!reader.IsDBNull(3))
                    {
                        user.Email = reader.GetString(3);
                    }
                }
                return user;
            }
        }
    }
}

LoginModel:用来传输数据的业务数据模型,为了避免三层之间的互相引用,独立于其他层的,其他层都会引用Model。

UserInfo.cs:

namespace Login.Model
{//Model是为了在三层之间传输数据的,他是独立与其他三个层次的。LoginModel不会引用任何程序集的。而其他的都会引用这个。
    public class UserInfo
    {//.net3.0支持这种写法:
        public int ID { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Email { get; set; }
    }
}

分析:最关键的是BLL层,三层的优势是职责分离,降低耦合。就像是一个餐厅,UI是服务员,我们任何需求都给服务员说,他相当于交互操作界面。服务员把菜单转给厨师,厨师就相当于BLL(业务逻辑层)负责业务处理和数据传递,比如告诉采购员DAL(数据访问层)白菜不够了,采购员就往仓库(数据库)中添加白菜(数据)。采购员对仓库进行操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值