前言:
学了三层之后,发现分层的好处就是可以实现解耦,但是不可能是完全解耦的,现在有了七层,可以更好的实现高内聚低耦合!
一、包图
为什么选择包图呢,包图呢其实就是一个包里有很多的类,在C#中可以当成一个命名空间,然后出现的包图如下!
如上图所示,你可能会问这不是8个包吗,为什么不是8层,其实完全可以,这都在于你个人,完全可以把SqlHelper当成一个独立的层!我的登陆系统是把SqlHelper放在D层中了,所以我的这个就是七层!
1、解释七层的用处
(1) UI:UI层,就是显示层,用户可以看到的界面,框架。。。。
(2)Facade:外观层,解除了UI层与BLL层之间的耦合
(3)逻辑层(BLL):执行逻辑判断
(4)接口层(IDAL):定义了统一的接口,DAL层实现接口,同时解除了BLL与DAL层的耦合
(6) 工厂层(Factory) 抽象工厂,利用配置文件选取相应的数据库
(7)数据访问层(DAL):与数据库进行相关的操作,(增删改查)
2、在访问完数据库的传值过程,如下图红线
二、代码
LoginUI层
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Data;
public partial class frmLogin : Form
{
public frmLogin()
{
InitializeComponent();
}
private void btnOK_Click(object sender, EventArgs e)
{
try
{
Entity.UserInfo user = new Entity.UserInfo();
user.UserID = Convert.ToInt32(txtUserName.Text.Trim());
user.Password = txtPassword.Text.Trim();
Boolean flag = false;
Facade.LoginFacade Flogin = new Facade.LoginFacade(); //实例化外观
flag = Flogin.SelectUser(user);
if (flag!=false)
{
this.Hide();//隐藏当前的窗体
this.DialogResult = System.Windows.Forms.DialogResult.OK;
frmMain newfrmlogin = new frmMain();
newfrmlogin.Show();
}
else
{
MessageBox.Show("密码或者用户名错误");
}
}
catch (Exception)
{
MessageBox.Show("用户名或密码不能为空,请重新输入", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key ="ConnStr" value="server=.; database=charge_sys;user ID = sa ; pwd=123456"/>
<!-- server是自己数据库的名字或者用.代表本地;把database,uid,pwd修改为与自己数据库对应的关系-->
<add key ="DB" value="DAL" />
</appSettings>
</configuration>
LoginFacade层
public class LoginFacade
{
public Boolean SelectUser(Entity.UserInfo user)
{
bool flag;
BLL.LoginBLL userBll = new BLL.LoginBLL();
flag = userBll.UserBLL(user);//这个flag表示的是如果有用户,那么就是true,如果没有那么返回值就是false
return flag;
}
}
LoginBLL层
using System.Data;
public class LoginBLL
{
public bool UserBLL(Entity.UserInfo UserInfo)
{
Factory.LoginFactory fact = new Factory.LoginFactory();//实例化工厂
IDAL.LoginIDAL idal = fact.CreateUser(); //调用工厂方法创建接口
DataTable table = idal.selectUser(UserInfo);//接收D层的返回值
bool flag;
if (table.Rows.Count == 0)//返回的是datatable的类型,如果他的行数等于0,说明没有符合该账号的密码的用户
{
flag = false;
}
else
{
flag = true;
}
return flag;
}
}
Factory层
using System.Configuration;
using System.Reflection;
public class LoginFactory
{
string StrDB = System.Configuration.ConfigurationManager.AppSettings["DB"];//接收来自配置文件的数据
public IDAL.LoginIDAL CreateUser()
{
string ClassName = StrDB + "." + "LoginADL";//DAL层的类名
return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);//反射的应用
}
}
IDAL层
using System.Data;//表示对ADO.NET结构类的访问,通过ADO.NET,可以生成有效管理多个数据源的数据的组件
public interface LoginIDAL
{
DataTable selectUser(Entity.UserInfo Userinfo);//DataTable表示内存中数据的一个表。实现了增删改查中的查!!!!
}
DAL层
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
public class LoginADL:IDAL.LoginIDAL
{
public DataTable selectUser(Entity.UserInfo Userinfo)
{
SqlHelper sqlhelper = new SqlHelper();
SqlParameter[] sqlParams = { new SqlParameter("@UserID", Userinfo.UserID), new SqlParameter("@Password", Userinfo.Password) };
string sql = @"SELECT * FROM User_Info WHERE UserID=@UserID AND PWD=@Password";
DataTable table = sqlhelper.ExecuteQuery(sql, sqlParams, CommandType.Text);
return table;//返回的是一个table的类型
}
}
SqlHelper
using System.Data;
using System.Configuration;//处理配置数据的类型
using System.Data.SqlClient;
public class SqlHelper
{
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;//从数据库中只读
public SqlHelper()
{
string connStr = ConfigurationManager.AppSettings["connStr"]; //Configuration//提供对客户端应用程序配置文件的访问。
conn = new SqlConnection(connStr);
}
private SqlConnection GetConn()//这个是判断数据库的连接
{
if (conn.State==ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
public DataTable ExecuteQuery(string cmdText, SqlParameter[] paras, CommandType ct)
{
DataTable dt = new DataTable();
cmd = new SqlCommand(cmdText,GetConn()); //cmdText查询的文本,getConn是上边的一个sqlconnection 它表示到sql server的连接!
cmd.CommandType = ct;//他的作用就是如何解释CommandText属性,commandtext就是指的是具体的什么指令(sql,或者什么存储过程)
cmd.Parameters.AddRange(paras);
using (sdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)) //ExecuteReader(CommandBehavior)将CommandText发送到Connection,并使用CommandBehavivor值之一生成SqlDataReader
{
dt.Load(sdr); //填充DataTable使用所提供的数据源中的值DataReader
}
return dt; //返回的是一个表
}
}
Entity层
public class UserInfo
{
//定义用户ID字段
private int _userid;
public int UserID
{
get { return _userid; }
set { _userid = value; }
}
private string _password;
public string Password
{
get
{
return _password;
}
set
{
_password = value;
}
}
}
后记:
思路要清晰,七层多去一步步调试,多去观察各层之间的关系!