概念:
UI层:给用户显示界面,接受用户输入的数据,并将输出结果返回给用户,就是平常我们使用的软件的登录界面。
Facade层:使用外观模式提供一个高层接口,负责U层与B层之间的信息传递,U层只需要和外观层的接口联系就可以达到目的。同样B层不需要知道U层的存在,这样通过进一步解耦,使U层和B层有变动的时候尽可能的减少影响。
BLL层:业务逻辑层,处理一些业务逻辑,在这里是通过抽象工厂设计模式实例化工厂,利用反射的思想来访问D层。
Factory层:工厂提供一个接口,通过抽象工厂的妙处,B层通过实例化接口指向的实例化对象,实现B层与D层的连接。
IDAL层:接口的作用,写了要实现的方法。
DAL层:数据访问层,与数据库直接交互,对数据进行增删改查的功能。
Entity层:实体层的作用是传递参数,它与每一次都可以关联,不断的被访问,保持着各层之间的联系、交流。
七层包图:
代码展示:
配置文件:
<?xml version="1.0" encoding="utf-8"?>
<!--版本-->
<configuration>
<!--定义配置类-->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<!-- 这里的配置文件用来连接数据库的,在XML配置文件中写入连接数据库的代码,方便打包后其他电脑进行数据连接,
其他电脑只需要在这里把关键信息改变为他的数据库名称便可以使用,不再需要重新生成等操作 -->
<!--节点,用来存储应用程序配置信息,如文件路径,xml Web services URL或存储在应用程序的.ini文件中的任何信息-->
<appSettings>
<!--数据库连接-->
<add key="connStr" value="Server=Tom;Database=Seven;User ID=sa;Password=123456" />
<!--DB-字符串,通过字符串找到对应的类库-->
<!--LoginDAL-类库名-->
<add key="DB" value="Login.DAL"/>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
</configuration>
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 butOK_Click(object sender, EventArgs e)
{
if (UserName.Text.Trim() == "")
{
MessageBox.Show("请输入你的用户名!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (Password.Text == "")
{
MessageBox.Show("请输入你的密码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
//实例化一个外观
Login.Facade.Facade facade = new Login.Facade.Facade();
//实例化一个用户
Login.Enitity.UserInfo user = new Login.Enitity.UserInfo();
//接受信息
user.UserName = UserName.Text;
user.Password = Password.Text;
//调用外观方法,返回给user
Boolean flag = false;
Login.Facade.Facade FLogin = new Login.Facade.Facade();
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("用户名或密码不正确");
}
}
private void txtUsername_TextChanged(object sender, EventArgs e)
{
}
}
}
Facade层:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Facade
{
public class Facade
{
//判断用户是否存在,并提供返回值flag
public Boolean SelectUser(Login.Enitity.UserInfo user)
{
bool flag;
Login.BLL.BLL userBLL = new Login.BLL.BLL();
flag = userBLL.UserBLL(user);
return flag;
}
}
}
BLL层:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using LoginIDAL;
namespace Login.BLL
{
public class BLL
{
//判断用户是否存在
public bool UserBLL(Enitity.UserInfo user)
{
//实例化工厂
Factory.Factory fact = new Factory.Factory();
IDAL dAL = fact.CreateUser(); //调用工厂方法创建接口
DataTable table = dAL.SelectUser(user); //接收D层的返回值
bool flag;
if (table.Rows.Count == 0) //返回数据表类型,如果行数=0,说明没有符合该账号密码的用户
{
flag = false;
}
else
{
flag = true;
}
return flag; //返回数值,帐号存在
}
}
}
Factory层:
本来想着使用反射获取配置文件的内容,结果不能,所以换了种方法,直接new一个LonginDal。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//命名空间
using System.Reflection;
using Login.DAL;
using System.Configuration.Assemblies;
using LoginIDAL;
namespace Login.Factory
{
//工厂层
public class Factory
{
//获取配置文件
// [Obsolete]
// string strDB = ConfigurationSettings.AppSettings ["DB"];
string strDB = System.Configuration.ConfigurationManager.AppSettings["DB"];
//应用反射来获取DAL层操作
//[Obsolete]
public IDAL CreateUser()
{
//string ClassName = "." + "LoginDal";
LoginDal loginDal = new LoginDal();
//IDAL a ;
//a = (IDAL)Assembly.Load(ClassName).CreateInstance(strDB.ClassName);//反射
return loginDal;
}
}
}
IDAL层:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LoginIDAL
{
public interface IDAL
{
//放置接口函数,判断要登录的用户名是否在数据表中存在
DataTable SelectUser(Login.Enitity.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 LoginIDAL;
using Login.Enitity;
namespace Login.DAL
{
public class LoginDal:IDAL
{
public DataTable SelectUser(Login.Enitity.UserInfo user)
{
//实例化数据操作类,进行数据查询,并获取返回值
SQLHelper sqlHelper = new SQLHelper();
SqlParameter[] sqlparams = {new SqlParameter("@UserName", user.UserName), new SqlParameter
("@Password", user.Password)};
string sql = @"SELECT * FROM [Users] WHERE UserName =@UserName AND Password = @Password";
DataTable table = sqlHelper.ExecuteQuery(sql, 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.Data.SqlClient;
using System.Configuration;
namespace Login.DAL
{
//数据访问层-数据操作类
public class SQLHelper
{
//定义数据库链接操作、指定在数据库上操作的类型、定义数据库读取操作
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;
//数据库连接
[Obsolete]
public SQLHelper()
{
string connstr = ConfigurationSettings.AppSettings["connstr"];
conn = new SqlConnection(connstr);
}
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
/// <summary>
/// 执行不带参数的数据库操作或者存储过程
/// </summary>
/// <param name="cmdText">增删改查操作</param>
/// <param name="ct">命令类型</param>
/// <returns>返回受影响的行数</returns>
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;
}
/// <summary>
/// 执行带参数的数据库操作或者存储过程
/// </summary>
/// <param name="cmdText">增删改查操作</param>
/// <param name="paras">要查询的参数</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;
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;
}
}
}
Enitity层:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Enitity
{
public class UserInfo
{
//定义用户ID属性
public int userID { get; set; }
//定义用户名UserNameshuxing
public string UserName { get; set; }
//定义密码Password属性
public string Password { get; set; }
}
}