七层登录

什么是七层?

其实七层也并没有那么复杂,无非在三层的基础上多扩展了三层而已。
  1. UI层:接收用户输入的数据,向用户展示要输出的信息
  2. Facade(外观层): 运用外观模式,提供 B 层的入口,降低 U 层和 B 层的耦合
  3. BLL层: 从 U 层中获取用户指令和数据,执行业务逻辑
  4. Factory(工厂层):返回一个 D 层对象。在工厂层中利用了反射,可以很方便的更换 D 层。
  5. IDAL(数据接口层):抽象了数据层中的方法,D层继承 IDAL 层。我认为它的意义所在就是更换 D 层时,直接创建类实现接口,以期可以很方便的和原来的 D 层保持一致。B 层可以通过接口调用具体的 D 层方法,正是利用了反射+多态才实现了数据库的易更换。
  6. DAL层:和数据源打交道,执行数据库的一些操作。
  7. Entity层:封装了信息,通过实体层的具体对象在各个层之间传递数据

通过七层和三层的比较,发现七层无非就是比三层多加了三层,而这三层的作用就是降低原来三层之间的耦合,可以更加灵活的扩展和修改。

包图

这里写图片描述

代码展示

Entity层

public class UserInfo
{        
    public Int64 userID { set; get; }
    public string userName { set; get; }
    public string password { set; get; }
    //用户等级
    public string level { set; get; }
    //此用户的开户人
    public Int64 registrantID { set; get; }
}

IDAL层

public interface IUserInfoDAL
{
    DataTable SelectUser(Entity.UserInfo userinfo);
}

DAL层

public class SQLHelper
{
    private SqlConnection conn = null;
    private SqlCommand cmd = null;
    private SqlDataReader sdr = null;

    public SQLHelper()
    {
        string connStr = ConfigurationManager.AppSettings["ConnStr"];
        conn = new SqlConnection(connStr);
    }
    /// <summary>
    /// 打开数据库连接
    /// </summary>
    /// <returns></returns>
    private SqlConnection GetConn()
    {
        if (conn.State == ConnectionState.Closed)
        {
            conn.Open();
        }
        return conn;
    }
    /// <summary>
    /// 执行不带参数的增删改SQL语句或存储过程
    /// </summary>
    /// <param name="cmdText">SQL语句或存储过程名</param>
    /// <param name="ct">执行的命令类型</param>
    /// <returns>受影响的行数</returns>
    public int ExecuteNonQuery(string cmdText, CommandType ct)
    {
        //受影响的行数
        int res;
        using (cmd = new SqlCommand(cmdText, GetConn()))
        {
            cmd.CommandType = ct;
            res = cmd.ExecuteNonQuery();
        }
        return res;
    }
    /// <summary>
    /// 执行带参数的增删改SQL语句或存储过程
    /// </summary>
    /// <param name="cmdText">SQL语句或者存储过程名</param>
    /// <param name="paras">SqlCommand参数集合</param>
    /// <param name="ct">执行的命令类型</param>
    /// <returns></returns>
    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;
    }
    /// <summary>
    /// 执行不带参数的查询SQL语句或存储过程
    /// </summary>
    /// <param name="cmdText">查询SQL语句或存储过程</param>
    /// <param name="ct">执行的命令类型</param>
    /// <returns></returns>
    public DataTable ExecuteQuery(string cmdText,CommandType ct)
    {
        DataTable dt = new DataTable();
        cmd = new SqlCommand(cmdText, GetConn());
        cmd.CommandType = ct;
        //CommandBehavior.CloseConnection的作用是dataReader关闭时其所对应的数据库连接也关闭
        using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            dt.Load(sdr);
        }
        return dt;
    }
    /// <summary>
    /// 执行带参数的SQL语句或存储过程
    /// </summary>
    /// <param name="cmdText">查询SQL语句或存储过程名</param>
    /// <param name="paras">参数集合</param>
    /// <param name="ct">执行的命令类型</param>
    /// <returns></returns>
    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;
    }
}
public class SqlUserInfoDAL : IDAL.IUserInfoDAL
{
    public DataTable SelectUser(UserInfo userinfo)
    {
        SQLHelper sqlHelper = new SQLHelper();
        string sql = "select * from User_Info where UserID=@userID and PWD = @password";
        SqlParameter[] paras = {new SqlParameter("@userID",userinfo.userID),
                                new SqlParameter("@password",userinfo.password)};
        return sqlHelper.ExecuteQuery(sql,paras, CommandType.Text);
    }
}

Factory层

public  class Factory
{
    //读取配置文件中所用数据库名称
    private static string strDB = System.Configuration.ConfigurationManager.AppSettings["DB"];
    //程序集名称
    private static string assemblyName = strDB + "DAL";

    public static IDAL.IUserInfoDAL CreateUserInfoDAL()
    {
        //要创建的类名
        string className = assemblyName + "." + strDB + "UserInfoDAL";
        return (IDAL.IUserInfoDAL)Assembly.Load(assemblyName).CreateInstance(className);
    }
}

BLL层

public class LoginBLL
{
    public bool SelectUser(Entity.UserInfo userInfo)
    {
        IDAL.IUserInfoDAL login = Factory.Factory.CreateUserInfoDAL();
        //B层调D层
        DataTable dt = login.SelectUser(userInfo);
        bool flag;
        //DataTable的总行数是0,则说明没有这个用户
        if (dt.Rows.Count == 0)
        {
            flag = false;
        }
        else
        {
            flag = true;
        }
        return flag;
    }
}

Facade层

public class LoginFacade
{
    public Boolean SelectUser(Entity.UserInfo userInfo)
    {            
        return new BLL.LoginBLL().SelectUser(userInfo);
    }
}

UI层

public partial class frmLogin : Form
{
    public frmLogin()
    {
        InitializeComponent();
    }

    private void btnLogin_Click(object sender, EventArgs e)
    {
        //判断输入不能为空
        if (txtUserID.Text.Trim() == "")
        {
            MessageBox.Show("请填写账号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
        if (txtPWD.Text == "")
        {
            MessageBox.Show("请填写密码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        try
        {
            Entity.UserInfo userInfo = new Entity.UserInfo();
            userInfo.userID = Convert.ToInt64(txtUserID.Text.Trim());
            userInfo.password = txtPWD.Text;

            Boolean flag = false;
            Facade.LoginFacade loginFacade = new Facade.LoginFacade();
            flag = loginFacade.SelectUser(userInfo);

            if (flag != false)
            {
                this.Hide();
                MessageBox.Show("登录成功!", "恭喜",MessageBoxButtons.OK);                    
            }
            else
            {
                MessageBox.Show("账号或者密码错误!");
            }
        }
        catch (Exception)
        {

            throw;
        }
    }
}
错误解决

在敲完之后需要执行的时候,可能会报以下两种错误:

这里写图片描述
这里写图片描述

以下提供三种解决方法:
①手动将 DAL 层生成的.dll文件拷贝到 UI 层的Debug文件夹中。
②更改 DAL 层编译后文件的生成路径
这里写图片描述
③修改 Factory 层中的代码
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值