C#版机房重构之七层登录

三层概述

数据访问层DAL(Data Access Layer)

(1)从数据源加载数据(Select)

(2)向数据源写入数据(Insert/Update)

(3)从数据源删除数据(Delete)

显示层UI

(1)向用户展现特定业务数据

(2)采集用户的输入信息的操作

UI设计的原则:用户至上,兼顾简洁

业务逻辑层BLL(Business Logic Layer)

(1)从DAL中获取数据,以供UI显示用

(2)从UI中获取用户指令和数据,执行业务逻辑

(3)从UI中获取用户和数据,通过DAL写入数据源

什么是七层?

七层就是在三层的基础上又增加了接口层、外观层、工厂层和实体层

1.实体层(Entity)存放全局的实体类,方便各个层之间的参数调用

2.数据访问层(DAL)该层所做事情是直接操作数据库,对数据的增删查改。不需要做什么逻辑判断,只是和数据库交互。

3.接口层(IDAL):接口层用来定义一个统一的接口,解除B层和D层的耦合。

4.工厂层(Factory):工厂来创建接口,返回接口,用到了抽象工厂+反射+配置文件,作用是灵活地实现数据库的连接,方便更换数据库

5.业务逻辑层(BLL):主要负责一些逻辑判断

6.外观层(Facade):用外观模式定义系统中每一层的入口,层与层之间不产生之间联系,而通过外观类建立联系,降低层之间的耦合度。

7.界面层(UI):主要职责是为用户提供信息并且接受用户输入的信息

包图

通过包图可以很清晰地看到各层之间的引用关系:

UI:Facade和Entity

Facade:BLL和Enetity

BLL:Factory、IDAL和Enetity

IDAL:Entity

Facotory:IDAL

DAL:IDAL和Entity

七层登录代码

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 UI
{
    public partial class frmLogin : Form
    {
        public frmLogin()
        {
            InitializeComponent();   //每一个窗体生成的时候,针对当前窗体界面的定义方法
        }
        //登录按钮
        private void btnLogin_Click(object sender, EventArgs e)
        {
            //判断卡号文本框是否输入为空
            if (txtCardno.Text.Trim() == "")
            {
                MessageBox.Show("请输入卡号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtCardno.Focus();
                return;     //return语句用来结束该方法或函数
            }
            //判断密码文本框是否输入为空
            if (txtPassword.Text.Trim() == "")
            {
                MessageBox.Show("请输入密码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPassword.Focus();
                return;
            }

            //实例化一个外观
            Facade.LoginFacade facade = new Facade.LoginFacade();

            //实例化一个用户
            Entity.UserInfo user = new Entity.UserInfo();

            //接收信息
            user.UserName = txtCardno.Text;     //将文本框中的卡号赋值给user的UserName属性
            user.Password = txtPassword.Text;   //将文本框中的密码赋值给user的Password属性

            //调用外观层的SelectUser()方法,返回一个bool值
            Boolean flag = false;
            Facade.LoginFacade flogin = new Facade.LoginFacade();
            flag = flogin.SelectUser(user);

            //判断是否登录成功
            if (flag!=false)
            {
                //显示登陆成功,隐藏当前窗体
                MessageBox.Show("登录成功");
                this.Hide();

                this.DialogResult = System.Windows.Forms.DialogResult.OK;   //类似于对话框点击了确定按钮
                Form a = new Form();        //实例化出一个新的窗体
                a.Show();
            }
            else
            {
                MessageBox.Show("用户名或密码不正确");
                txtCardno.Text = "";
                txtPassword.Text = "";
                txtCardno.Focus();
            }
            
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确认退出系统吗?","提示",MessageBoxButtons.OKCancel,MessageBoxIcon.Asterisk)==DialogResult.OK)   //对话框点击了确定就强制退出
            {
                System.Environment.Exit(0);  //强制退出
            }
        }
    }
}

App.cnofig配置文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <appSettings>
      <!--Connstr连接数据库,key,value 是一个键值对,key为键,value为值,根据key可以找到value值-->
      <add key="connStr" value="server=DESKTOP-DHFP31D; database=wtt; uid=sa; password=123456" />
      <add key="DB" value="DAL" />
    </appSettings>
</configuration>

Entity实体层

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

namespace Entity
{
    public class UserInfo
    {
        //定义用户名字段属性
        private string _username;
        public string UserName
        {
            get { return _username; }
            set { _username = value; }
        }

        //定义密码Password字段属性
        private string _password;
        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }
    }
}

Facade外观层

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

namespace Facade
{
    public class LoginFacade
    {
        public Boolean SelectUser(Entity.UserInfo user)
        {
            bool flag;                              //标记常量
            LoginBLL userBLL = new LoginBLL();      //实例化一个LoginBLL类
            flag = userBLL.UserBLL(user);           //跳转到BLL层
            return flag;
        }
    }
}

BLL业务逻辑层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Collections;
using Factory;
using IDAL;
using Entity;

namespace BLL
{
    public class LoginBLL
    {
        //判断用户是否存在
        public bool UserBLL(Entity.UserInfo user)
        {
            //实例化工厂
            Factory.LoginFactory fact = new Factory.LoginFactory();

            //调用工厂方法创建接口
            IDAL.LoginIDAL idal = fact.CreateUser();

            //接收D层的返回值
            DataTable table = idal.SelectUser(user);

            bool flag;
            //返回数据表类型,如果行数=0,说明没有符合该账号密码的用户
            if (table.Rows.Count==0)
            {
                flag = false;
            }
            else
            {
                flag = true;
            }
            return flag;
        }
    }
}

Factory工厂层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Configuration;
using IDAL;

namespace Factory
{
    public class LoginFactory
    {
        //获取配置文件
        string strDB = System.Configuration.ConfigurationManager.AppSettings["DB"];

        //应用反射来获取DAL层操作
        public IDAL.LoginIDAL CreateUser()
        {
            string ClassName = strDB + "." + "LoginDAL";        //程序集+类名
            return (IDAL.LoginIDAL)Assembly.Load(strDB).CreateInstance(ClassName);     //反射+工厂
        }
    }
}

IDAL接口层

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

namespace IDAL
{
    //接口层
    public interface LoginIDAL
    {
        //放置接口函数,判断要登录的用户名是否在数据表中存在
        DataTable SelectUser(Entity.UserInfo user);
    }
}

DAL数据访问层

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

namespace DAL
{
    public class LoginDAL:LoginIDAL
    {
        public DataTable SelectUser(Entity.UserInfo user)   //SelectUser方法是IDAL接口的方法
        {
            //实例化数据库操作类,进行数据查询,并获取返回值
            SqlHelper sqlHelper = new SqlHelper();
            SqlParameter[] sqlparams = { new SqlParameter("@cardno",user.UserName), new SqlParameter("@password",user.Password)};
            string sqlquery = @"SELECT * FROM [card_info] WHERE cardno=@cardno AND password=@password";     //sql查询语句

            DataTable table = sqlHelper.ExecuteQuery(sqlquery, sqlparams, CommandType.Text);
            return table;
        }
    }
}

SqlHelper类

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

namespace DAL
{
    public class SqlHelper
    {
        //定义数据库连接操作,指定在数据上操作的类型,定义数据库读取操作
        private SqlConnection conn = null;  //SqlConnection中表示数据库一个打开的连接
        private SqlCommand cmd = null;      //SqlCommand表示SQL Server数据库执行一个Transact-SQL语句或者存储过程
        private SqlDataReader sdr = null;   //sqlDataReader提供一种从SQL Server数据库读取行的只进流的方式

        //数据库连接
        public SqlHelper()
        {
            string connStr = null;
            connStr = ConfigurationManager.AppSettings["connStr"];
            conn = new SqlConnection(connStr);      //实例化一个连接
        }
        private SqlConnection GetConn()
        {
            if (conn.State==ConnectionState.Closed)     //连接状态为关闭
            {
                conn.Open();        //打开连接
            }
            return conn;
        }

        //执行不带参数的数据库操作或存储过程
        public int ExecuteNonQuery(string cmdText, CommandType ct)
        {
            int res;
            cmd = new SqlCommand(cmdText, GetConn());       //打开连接
            cmd.CommandType = ct;
            res = cmd.ExecuteNonQuery();
            if (conn.State==ConnectionState.Open)       //连接处于打开状态
            {
                conn.Close();      //关闭
            }
            return res;
        }

        //执行带参数的数据库操作或存储过程
        public int ExecuteNonQuery(string cmdText, SqlParameter[] paras, CommandType ct)
        {
            int res;
            using (cmd = new SqlCommand(cmdText, GetConn()))
            {
                cmd.CommandType = ct;
                cmd.Parameters.AddRange(paras);
                res = cmd.ExecuteNonQuery();
            }
            return res;
        }

        //执行不带参数的SQL查询语句或存储过程
        public DataTable ExecuteQuery(string cmdText, CommandType ct)
        {
            DataTable dt = new DataTable();
            cmd = new SqlCommand(cmdText, GetConn());
            cmd.CommandType = ct;
            using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                dt.Load(sdr);
            }
            return dt;

        }

        //执行带参数的SQL查询语句或存储过程
        public DataTable ExecuteQuery(string cmdText, SqlParameter[] paras, CommandType ct)
        {
            DataTable dt = new DataTable();
            cmd = new SqlCommand(cmdText, GetConn());
            cmd.CommandType = ct;
            cmd.Parameters.AddRange(paras);
            using (sdr=cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                dt.Load(sdr);
            }
            return dt;
        }
    }
}

Genuine knowledge comes from practice.

实践出真知,不要觉得它难,去做就好。

         

猜你喜欢

转载自blog.csdn.net/wtt15100/article/details/106194071
今日推荐