七层是指哪七层?与三层相比多了哪几层呢?各层之间的关系又是怎样的呢?七层就是在三层的基础上,添加了外观层(也就是设计模式的外观模式),抽象工厂加反射,接口层。外观层主要是在UI层和BLL层之间实现解耦;抽象工厂加反射主要是为了方便更换数据库,同时把DAL层中的类转换成IDAL层中的接口,从而使BLL层实现通过调用IDAL从而调用DAL层;接口层主要是为了在BLL层和DAL层之间实现解耦。
一、七层的组成
1、界面层(UI):主要用于收集用户输入的数据然后传给外观层,再由外观层传给B层进行相应的判断。
2、业务逻辑层(BLL):主要是进行逻辑判断的,调用工厂中的方法创建相应的接口。
3、数据访问层(DAL):实现接口层定义的接口。
4、外观层(Facade):运用外观层的目的是降低U层和B层之间的耦合,U层和B层之间的联系只需要通过Facade层的接口就行了,U层无需知道B层内部有哪些方法。外观层接收U层传来的数据,然后调用B层的方法对信息进行验证。
5、工厂层(Factory):通过配置文件和抽象工厂我们可以实现不更改代码,换一下配置文件中的value值就可以更换数据库了。Factory还需要完成的工作就是定义一个接口调用接口层,实现BLL层和DAL层之间的数据传递。
6、接口层(IDAL):接口层是用于定义一个统一的接口,解除B层和D层的耦合。
7、实体层(Entity):和三层中的实体层一样,主要是用来在各层中传递数据。
除此之外,还有SQLHelper,它将D层中需要重复使用的连接数据库代码抽象到一个层里面了,这样就不用重复的写这些代码。
了,减少了冗余。
二、各层之间的关系
三、各层代码
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<!--这里的配置文件是用来连接数据库的。在XML配置文件中写入连接数据库的代码方便打包后其他电脑进行数据连接,其他电脑只需在这里吧关键信息改变为它的数据库名称便可以使用,不再需要重新生成等操作-->
<appSettings>
<add key="DB" value="DAL"/>
<add key="connStr" value="Server=DESKTOP-NI3TBLD;Database=Login;uid=sa;Password=123456"/>
</appSettings>
</configuration>
SQLHelper
public class SQLHelper
{
//定义数据库连接操作、指定在数据库上操作的类型、定义数据库读取操作
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;
/// <summary>
/// 数据库连接
/// </summary>
public SQLHelper()
{
string connStr = ConfigurationManager.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"></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"></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;
}
}
Entity层
public class UserInfo
{
//定义用户ID的UserID属性
public string UserID { get; set; }
//定义用户名UserName的属性
public string UserName { get; set; }
//定义密码Password属性
public string Password { get; set; }
//定义用户级别UserLevel的属性
public string UserLevel { get; set; }
}
DAL层
public class LoginDAL:IDAL.LoginIDAL
{
public DataTable SelectUser(Entity.UserInfo user)
{
//实例化数据操作类,进行数据查询,并获取返回值
SQLHelper sqlHelper = new SQLHelper();
SqlParameter[] sqlparams = { new SqlParameter("@UserID", user.UserID), new SqlParameter("@Password", user.Password) };
string sql = @"SELECT * FROM Users WHERE UserID=@UserID AND Password=@Password";//构造语句,匹配数据库表
DataTable table = sqlHelper.ExecuteQuery(sql, sqlparams, CommandType.Text);
return table;
}
}
IDAL层
public interface LoginIDAL
{
//接口函数,判断要登录的用户名是否在数据表中存在
DataTable SelectUser(Entity.UserInfo user);
}
Factory层
//工厂层
public class LoginFactory
{
//获取配置文件
string StrDB = ConfigurationManager.AppSettings["DB"];
//应用反射来获取DAL层操作
public IDAL.LoginIDAL CreateUser()
{
string ClassName = StrDB + "." + "LoginDAL";
return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);
}
}
BLL层
//业务逻辑层
public class LoginBLL
{
//判断用户是否存在
public bool UserBll(Entity.UserInfo user)
{
Factory.LoginFactory fact = new Factory.LoginFactory(); //实例化工厂
IDAL.LoginIDAL idal=fact.CreateUser(); //调用工厂方法创建接口
DataTable table = idal.SelectUser(user); //接受D层的返回值
bool flag;
if (table.Rows.Count==0) //返回数据表类型,如果行数=0,说明没有符合该账号密码的用户
{
flag = false;
}
else
{
flag = true;
}
return flag; //返回数值,账号存在
}
}
Facade层
public class LoginFacade
{
//判断用户是否存在,并提供返回值flag
public Boolean SelectUser(Entity.UserInfo user)
{
bool flag;
BLL.LoginBLL userBll = new BLL.LoginBLL();
flag = userBll.UserBll(user);
return flag;
}
}
UI层
public partial class frmLogin : Form
{
public static string UserID;
public static string Password;
public frmLogin()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
if (txtUserID.Text.Trim()=="")
{
MessageBox.Show("请输入用户名!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtUserID.Focus();
}
if (txtPassword.Text=="")
{
MessageBox.Show("请输入密码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtPassword.Focus();
}
//实例化一个外观
Facade.LoginFacade facade = new LoginFacade();
//实例化一个用户
Entity.UserInfo user = new Entity.UserInfo();
//接受信息
user.UserID = txtUserID.Text;
UserID = user.UserID;
user.Password = txtPassword.Text;
Password = txtPassword.Text;
Boolean flag = false;
//实例化外观
Facade.LoginFacade FLogin = new LoginFacade();
//调用外观方法,返回给user
flag = FLogin.SelectUser(user);
//判断是否登录成功false
if (flag!=false)
{
this.Hide(); //隐藏当前窗体
this.DialogResult = System.Windows.Forms.DialogResult.OK;
frmOrdinary frmOrdinary = new frmOrdinary();
frmOrdinary.Show();
}
else
{
MessageBox.Show("用户名或密码不正确!");
}
}
}
很早之前就该发出的博客,直到今天才发,最近事情太多,需要好好规划了!
感谢阅读~