C#之三层登录

最近学习了三层结构,这三层结构分别是界面层(User Interface layer),业务逻辑层(Business Logic Layer),数据访问层(Data access layer)。为什么要分层,从官方角度来说就是降低前台于后端之间的耦合度,解释一下就是前台指界面层,后台可以理解为数据库,如果没有中间的逻辑层和数据访问层来分解的话,所有的事情基本上都是界面层在干,好比一个公司只有一个员工,那么这个公司的所有工作只有一个人来干,那么在资源有限情况下,任务处理速度自然无线降低,工作效率就自然不用说,如果一个公司有足够的员工,并且各司其职,同样的资源,却会发挥出更高的工作效率,自然任务处理速度增加。

界面层(UI):展示给用户的界面,可以接受用户输入信息,也给用户展示返回的信息。

业务逻辑层(BLL):调用相关的数据访问类,对数据层的操作和业务的处理,对用户输入的信息进行处理,并把返回值返回给界面层,实现用户所需功能。

数据访问层(DAL):直接操纵数据库,主要是曾删改查的功能,实现进本记录操作。

三层设计的优缺点:

优点:

1、开发人员可以只关注整个结构中的其中某一层;

2、可以很容易的用新的实现来替换原有层次的实现;

3、可以降低层与层之间的依赖;

4、有利于标准化;

5、利于各层逻辑的复用。

扫描二维码关注公众号,回复: 12586583 查看本文章

缺点:

1、降低了系统的性能。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

三层实际操作:

引用:

路径:解决方案资源管理器视图→项目→右键单击,添加引用→项目→勾选项目名称单击确定即可。

UI:BLL,Model。BLL:DAL,Model。DAL:Model。提示:千万不要全部都引用,因为会出现循环引用错误,而且,用哪个引用哪个。不要多用,导致出现引用循环。

在写代码前需要说明的是,我的程序集名称是LoginBLL,默认命名空间是Login.BLL,中间多加了一个点,在实例化的过程中这是一个非常容易出错的地方,如果你不是自己写的代码,请注意命名规范。

首先我们来建立数据访问层(DAL):

Dbutil类:

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

namespace Login.DAL
{
    class Dbutil
    {
        //登录SQL Server代码
        public static string ConnString = @"Server=(Local); Database=Login; User=sa; Password=123456";
    }
}

ScoreDAO类

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

namespace Login.DAL
{
    public class ScoreDAO
    {
        public void UpdateScore(string userName,int value)//加分
        {
            //using 打开了数据库连接,从数据库中读取数据。
            using (SqlConnection conn = new SqlConnection(Dbutil.ConnString))
            {
                //sqlcommand 表示可以对SQL Server数据库进行的操作。
                SqlCommand cmd = conn.CreateCommand();

                //获取数据表名
                cmd.CommandText = @"INSERT INTO Score(UserName,Score) Values(@UserName,@Score)";

                //声明两个参数. Parameters是范围的意思。
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));
                cmd.Parameters.Add(new SqlParameter("@Score", value));

                //登录数据库
                conn.Open();
                cmd.ExecuteNonQuery();//必须引用using System.Data.SqlClient;此代码用来更新数据库。
            }
        }
    }
}

UserDAO类

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

namespace Login.DAL
{
    public class UserDAO
    {
        //
        public Login.Model.UserInfo SelectUser(string userName,string password)
        {
            //using 打开了数据库连接,从数据库中读取数据。
            using(SqlConnection conn = new SqlConnection(Dbutil.ConnString))//此行代码是登录SQL Server用的
            {
                //sqlcommand 表示可以对SQL server数据库进行的操作
                SqlCommand cmd = conn.CreateCommand();

                //获取数据表名
                cmd.CommandText = @"SELECT ID,UserName,Password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password";

                //二CommandType是一个枚举类型。有三个值:text,StoredProcedure,TableDirect用于标书SqlCommand对象Commandtype的执行形式。
                cmd.CommandType = System.Data.CommandType.Text;//不写也可以的,因为Text是默认的

                //声明两个参数。Parameters是范围的意思。查询条件。
                cmd.Parameters.Add(new SqlParameter("@UserName", userName));
                cmd.Parameters.Add(new SqlParameter("@Password", password));

                //登录数据库
                conn.Open();

                //想要使用SQLDateReader,就必须引用上面的client命名空间。并且如果想创建SQLDateReader,就必须使用ExecuteReader方法。
                SqlDataReader reader = cmd.ExecuteReader();//对数据库进行查询得到结果,并且返回对象。

                Login.Model.UserInfo user = null;//先构造LoginModel,首先默认值为Null

                while (reader.Read())//开始读取数据,如果用户名和密码不正确,无法读取数据,直接返回user为null
                {
                    if(user==null)//如果null的话,在进行构造。
                    {
                        user = new Login.Model.UserInfo();
                    }
                    user.ID = reader.GetInt32(0);
                    user.UserName = reader.GetString(1);
                    user.Password = reader.GetString(2);
                    if (!reader.IsDBNull(3))
                    {
                        user.Email = reader.GetString(3);
                    }
                }
                return user;
            }
        }
    }
}

业务逻辑层(BLL):

LoginManager类:

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

namespace Login.BLL
{
    public class LoginManager
    {
        public Login.Model.UserInfo UserLogin(string userName,string password)//获取用户传来的信息
        {
            //需要和数据源打交道,实例化DAL层
            Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();

            Login.Model.UserInfo user = uDao.SelectUser(userName, password);
            if (user != null)//登录成功时
            {
                Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();//增加积分。
                sDao.UpdateScore(userName, 10);
                return user;
            }
            else
            {
                throw new Exception("登录失败");//登录不成功跳到这里
            }
        }
    }
}

界面层(UI):

注意命名,已经更改。

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 LoginUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            string userName = txtUserName.Text.Trim();
            string password = txtPassword.Text;

            //实例化这个业务层类
            Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();

            //将信息给model层
            Login.Model.UserInfo user = mgr.UserLogin(userName, password);

            //返回UI层
            MessageBox.Show("登录用户:" + user.UserName);
        }
    }
}

Model层:

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

namespace Login.Model
{
    public class UserInfo
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Email { get; set; }
    }
}

最后总结了一点,自己写代码的时候注意自己的命名规范,我在后边的时候,出现的错误基本上都是命名出现的错误,尤其是在借用别人的代码的时候,命名不一致的时候是最致命的,一般情况下会出现引用问题,但是有时候是using的,有时候是引用的程序集问题,数据库的链接符也比较容易出现命名不一致的问题,这是我对于三层第一次实践出现比较常见的问题。

猜你喜欢

转载自blog.csdn.net/weixin_37081112/article/details/103903670