博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]C#三层架构登陆实例
阅读量:5873 次
发布时间:2019-06-19

本文共 5858 字,大约阅读时间需要 19 分钟。

很早之前,就听说过三层结构了。当时只知道 三层结构 是把 系统的 界面  跟 数据库操作等不相关的程序分别开来。原来这么简单的实现,确实传说中的 三层结构啊。

    首先,先来看一下是哪三层。表示层(UI,User Interface),业务逻辑层(BLL BusinessLogicLayer),数据访问层(DAL Data Access Layer)。三层的划分是物理上的划分。

 

    表示层(UI),这个最容易理解,就是用户看到的主界面。

    数据访问层(DAL),也不难理解,主要是负责数据的增删改查。

    业务逻辑层(BLL),算是表示层和数据访问层的桥梁吧。里面主要存放一些业务流程。也就是逻辑。主要作用就是从DAL中获取数据,然后显示到UI上。

 

    举一个例子,三层结构可以用饭店的实例来理解。

 UI指的是服务员,BLL是厨师,DAL是采购员。

    在顾客的眼里,只能看到服务员为他们服务。并不知道后台厨师和采购员是如何做的。对于上述三种不同的角色来说,无论哪个环节出了问题,只需要更换一个员工就可以照常营业的。

三层架构的优势,还是职责分离,降低耦合。

 

    接下来,看一个使用三层结构的登陆实例。首先,需要声明一下。这个实例中有很多bug需要优化。不过对于展示三层的主要思想足够了。仅仅是一个实例而已。

数据库表:

这是数据模块图:

 细心的读者肯定会发现,除了UI,BLL,DAL这三个之外还有一个Model存在,这个Model不属于任何一层,只是为了更好地链接三层而存在的。这个类只存储,与以上三类共同使用的东西。起一个协调的作用。Model类,也就是实体类Entity。

    下面是这几个层次的关系。

    下面是源代码分析。

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; }    }}

U层:

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 label1_Click(object sender, EventArgs e)        {        }        private void btnLogin_Click(object sender, EventArgs e)        {            try            {                string userName = txtUserName.Text.Trim();   //取出用户界面的数据                string password = txtPassword.Text;                Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();                Login.Model.UserInfo user = mgr.UserLogin(userName, password);   //使用用户界面数据 进行查找                //如果没有问题,则登陆成功                MessageBox.Show("登陆用户:" + user.UserName);            }            catch (Exception ex)   //如果登陆有异常 则登陆失败            {                MessageBox.Show(ex.Message);            }        }    }}

B层:

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)        {            ///throw new NotImplementedException();            Login.DAL.UserDAO uDAO = new Login.DAL.UserDAO();  //创建一个user            Login.Model.UserInfo user= uDAO.SelectUser(userName, Password);  //通过ui中填写的内容 返回来相应的数据            if (user!= null)        //如果数据库中没有数据,即为首次登陆了。增加10积分            {                Login.DAL.ScoreDAO sDAO = new Login.DAL.ScoreDAO();                 sDAO.UpdateScore(userName, 10);                return user;            }            else       //如果数据库中没有该用户名,则登陆失败            {                                 throw new Exception("登陆失败");            }        }    }}

D层:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Login.DAL     //数据访问层{    class DbUtil        //用于保存 链接服务器的sql语句    {        public static string ConnString = @"Server=zc-pc;Database=Login;User ID=sa; Password=123456";    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data;using System.Data.SqlClient;namespace Login.DAL{    public class UserDAO    {        public Login.Model.UserInfo SelectUser(string userName, string Password)   //根据 ui 选择返回一个user        {            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;                cmd.Parameters.Add(new SqlParameter("@userName", userName));                cmd.Parameters.Add(new SqlParameter("@Password", Password));                conn.Open();        //打开数据链接                SqlDataReader reader= cmd.ExecuteReader();                                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);                    user.Password=reader.GetString(2);                    if(!reader.IsDBNull(3))         //不要求一定要有email,也可以返回                    {                        user.Email=reader.GetString(3);                    }                                    }                return user;            }                    }    }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data.SqlClient;namespace Login.DAL{    public class ScoreDAO     //首次登陆,增加10积分    {        public void UpdateScore(string userName, int value)        {            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))            {                SqlCommand cmd = conn.CreateCommand();  //创建一个命令对象                cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values(@UserName,@Score)";  //修改Score表数据                cmd.Parameters.Add(new SqlParameter("@userName", userName));                cmd.Parameters.Add(new SqlParameter("@Score", value));                conn.Open();                cmd.ExecuteNonQuery();            }        }    }}

接下来,看一下执行结果:

执行成功的情况:

输入错误信息:

虽然这是一个很小的实例,但是用来学习三层却足够了。有写的不好的地方可以理解。

    总结:对于使用三层架构的程序来说,哪层出错改哪里。极大程度的降低了系统的耦合性。当然,具有层次的程序,维护起来必然要方便许多。

原文链接:

 

转载地址:http://ichnx.baihongyu.com/

你可能感兴趣的文章
Ehcache 缓存
查看>>
list删除重复元素
查看>>
绘制屏幕时给单选按钮分组
查看>>
TCP/IP协议、DoD模型、OSI模型
查看>>
java开发环境
查看>>
Can't create handler inside thread that has not called Looper.prepare()
查看>>
ADB命令详解
查看>>
urllib模块学习
查看>>
Flume案例Ganglia监控
查看>>
HDU 4001 To Miss Our Children Time DP
查看>>
12C 新特性--全库缓存
查看>>
中国科学院数学与系统科学研究院关于2019年招收硕士研究生复试规程
查看>>
在Github中创建项目并与本地关联
查看>>
Qt的quit(),exit()以及close()事件捕获
查看>>
1002. 写出这个数 (20)
查看>>
普通软件项目开发过程规范(五)—— 总结
查看>>
css 样式(checkbox开关、css按钮)
查看>>
PS打造油画般的风景人像
查看>>
JS_高程3.基本概念(2)
查看>>
Leetcode 俄罗斯套娃信封问题
查看>>