【C#】机房重构七层登录

第一次敲机房入门用了不到三天,敲机房重构入门用了一个礼拜,自己的进步在哪呢?

登录界面:

登录的时候需要判断两张表,一张是User表,里面放的是管理员和操作员,一张是Student表,里面放的是一般用户。由于自己懒外加笨,所以就设置了两个登录界面。一般用户登录后是自己一个单独的窗体,只有自己的功能,操作员和管理员登录也只具备自己该有的功能,除了查询外不具有一般用户的功能。如下是初始模板,比较丑,后期在进行完善:

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;
using Entity;


namespace UI
{
    public partial class FrmLogin : Form
    {
        public FrmLogin()
        {
            InitializeComponent();
        }
        public static string id;//方便后面的修改密码的窗体使用。
        public static string stucardno;

         //管理员或者操作员登录  
        private void btLogin_Click(object sender, EventArgs e)
        {
            if (txtUserName.Text.Trim() == "")
            {
                MessageBox.Show("用户ID不能为空,请您输入用户名");
                return;//不继续往下走
            }
            if (txtPassword.Text == "")
            {
                MessageBox.Show("密码不能为空,请您输入密码");
                return;
            }
          
            Entity.User_Info user = new Entity.User_Info();//实例化实体层
            user.userID = txtUserName.Text.Trim();//将UI层的用户名传给相应的实体层
            user.PWD = txtPassword.Text.Trim();//将UI层的密码也传给相应的实体层

            Boolean flag = false;//bool就像是小名,boolean是大名,其实意思都一样。
            Facade.LoginFacade fact = new Facade.LoginFacade();//实例化一个外观层
            flag = fact.SelectUser(user);//调用外观层的方法
            if (flag != false)
            {               
                this.Hide();
                id = txtUserName.Text.Trim();
                MessageBox.Show("登录成功");              
                this.DialogResult = DialogResult.OK;               
            }
            else
            {
                MessageBox.Show("密码或者用户名错误");
                return;
            }            
           
        }
        private void btCancel_Click(object sender, EventArgs e)
        {
            this.Close();          
        }

    }

}

Facade层,门面层,举个例子:它就像进医院的门口接待员一样,客户端不需要直接访问医院内部复杂的结构,只需要和接待员打交道就好,降低了UI层和BLL层之间的耦合度。(来源于百度例子)

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

namespace Facade
{
   public class LoginFacade
    {
        public Boolean SelectUser(Entity.User_Info user)
        {
            bool flag;
            BLL.LoginManager man = new BLL.LoginManager(); //实例化B层
            flag = man.UserBLL(user);//调用B层,将查询的结果给flag
            return flag;//返回U层
        }
    }
}

BLL层(Business Logic Layer):业务逻辑层。进行逻辑判断和存放功能函数,连接DAL层,但是为了降低耦合度,需要Factory层和IDAL层的帮助。

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

namespace BLL
{
   public class LoginManager
    {
        public bool UserBLL(Entity.User_Info userInfo)
        {
            Factory.LoginFacory Fact = new Factory.LoginFacory();//实例化一个工厂
            IDAL.ILoginIDAL idal = Fact.CreateUser();//调取工厂中的方法,利用反射机制实例化DAL层。这里本来应该是DAL,换成了它的父类,IDAL,依赖于抽象。

            DataTable table = idal.SelectUser(userInfo);//调取DAL层的方法,DAL层中的SelectUser继承了抽象工厂的方法。

            bool flag;
            if (table.Rows.Count == 0)//如果新的更新后的表中是空的,则····
            {
                flag = false;
            }
            else
            {
                flag = true;
            }
            return flag;//返回外观层
        }     
    }   
}

Factory层,Factory层只是实现接口而已,作为BLL和DAL之间的桥梁,说白了就是连接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.Reflection;
using System.Configuration;
using System.IO;

namespace Factory//灵活的配制文件;面向的是抽象,而不是细节。
{
    public class LoginFacory
    {
        //读取配制文件
        string StrDB =ConfigurationManager.AppSettings["DB"];//从confilg配制文件中获取key值为“DB”的value,就是配制文件里的DAL。

        public IDAL.ILoginIDAL CreateUser()
        {
            string ClassName = StrDB + "." + "LoginDAL";//DAL.LoginDAL;
            return (IDAL.ILoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);
            //对上面的解释:Assembly.Load()在给定程序集的情况下,加载该程序集+程序集名称,CreateInstance+当前命名空间名称。返回到DAL.LoginDAL。(反射)
            
        }


    }
}

IDAL层,提供接口,DAL需要继承相应的IDLA层。

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

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

DAL层(Data Access Layer):数据访问层访问数据库并返回一个表的层。

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;

namespace DAL
{
    public class LoginDAL : IDAL.ILoginIDAL//继承接口
    {
        //从User表中查询信息
        public DataTable SelectUser(Entity.User_Info userInfo)
        {
            SQLHelper sqlHelper = new SQLHelper();//实例化一个数据查询的对象,此代码的作用是连接数据库。

            SqlParameter[] sqlParams = { new SqlParameter("@userID", userInfo.userID),
                                         new SqlParameter("@password", userInfo.PWD) };//SqlParameter是范围的意思,个人理解这行代码是规定新的东西。就是将PWD换成@password。
            string sql = @"SELECT * FROM User_Info WHERE userID=@userID and PWD=@password";//查询数据库
            DataTable table = sqlHelper.ExecuteQuery1(sql, sqlParams, CommandType.Text);/*SQLHelper查询,里面的参数依次是数据库查询、
                                                                                      设置新参数、默认的枚举类型。返回的table是一个新的数据表*/
            return table;//新的更新后的表
        }
                                    
    }
}

SQLHelper层,放在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;
namespace DAL
{
    public class SQLHelper
    {
        //sqlHelper的封装在DAL层,目的连接数据库,实现对数据库的增删改查的操作,所以sqlHelper不可以当做一层来看待,存在的目的服务于DAL层。定义数据库连接操作,指定在数据库上操作的类型、定义数据库读取操作。
        
        private SqlConnection conn = null;  
        private SqlCommand cmd = null;  
        private SqlDataReader sdr = null;

        public SQLHelper()
        {
            //ConfigurationManager表示读配置文件
            string connStr = ConfigurationManager.AppSettings["connStr"];//读取数据库,ConnStr是从配置文件里面连接数据库的关键字。
            conn = new SqlConnection(connStr);//连接数据库
        }
        private SqlConnection GetConn()
        {
            if (conn.State == ConnectionState.Closed)//表示当前的连接如果是关闭状态,则打开
            {
                conn.Open();
            }
            return conn;
        }

        //执行不带参数的增删改SQL语句或者存储过程
        public int ExecuteNonQuery(string cmdText, CommandType ct)
        {
            int res;
            try
            {
                cmd = new SqlCommand(cmdText, GetConn());
                cmd.CommandType = ct;
                res = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conn.State == ConnectionState.Closed)
                {
                    conn.Close();
                }
            }
            return res;
        }

        //执行带参数的增删改SQL语句或者存储过程
        public int ExecuteQuery(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 ExecuteNonQuery1(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 ExecuteQuery1(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;
        }

    }
}

Entity层,实体层,存放数据库中的内容,使操作更方便。

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

namespace Entity//把数据库里面的字段拿出来使用,比较方便。
{
   public class User_Info
    {
        public string userID { get; set; }
        public string UserName { get; set; }
        public string PWD { get; set; }
        public string Level { get; set; }
       
    }
}
发布了109 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/aaaPostcard/article/details/97554462
今日推荐