实体层
我在这先简单介绍一下实体层,这是一个处在“三界之外”的东西,它不属于任何一层,但是任何一层都和它有关联,为什么会在三层中出现这么一层呢?其实这一层就是在经典三层传送数据的,避免三层之间的交叉调用,更好的解耦。也许有同学问那么直接传送变量参数不就完了吗?当参数只有一个或者两个的时候看不出效果,但是当我的参数多的时候呢?比如我们传送学生信息,那么我们就需要N个参数,那样的程序是不能要的。
所以我们将这些参数封装成一个实体,用get()和set()方法来操作,这样就简单多了,也更好的体现了面向对象的思想。我们可以简单的理解实体为数据库中的一张表,这样理解不是错的,但是当涉及到多个表的时候就返回不了实体类了,需要基于视图来创建实体类。那么我们就可以将所有表的所有字段都放在这个实体类中,这说明我们可以根据自己的需要来创建自己的实体类,怎样符合怎样用就可以,没有死规定。
下面来看一下这个小例子的架构:
来看一下代码的实现:
实体层代码:
public class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
封装了一个实体。
U层代码:
private void btLogin_Click(object sender, EventArgs e)
{
string userName = txtUserName.Text.Trim ();
string password = txtPassword .Text;
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
Login.Model .UserInfo user= mgr.UserLogin(userName ,password );
MessageBox.Show("登录用户:" + user.UserName);
}
从界面中获取两个参数传给B层。
B层代码:
public class LoginManager
{
public Login.Model.UserInfo UserLogin(string userName, string password)
{
Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();
//需要访问数据源,所以实例化一个D层UserDAO对象
Login.Model.UserInfo user = uDao.SelectUser(userName, password);
if (user != null)
{
Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
sDao.UpdateScore(userName, 10);
return user; //往U层传数据
}
else
{
throw new Exception("登录失败:");
}
B层起着承上启下的作用,在正向的时候将数据从U层床送到D层,在反向的时候从D层传送到U层,在这个传送的过程中根据需要,进行了相应的逻辑判断,这正是B层的作用,是U层不在和D层直接交互,起到解耦的作用。
D层代码:
public class UserDAO
{
public Login.Model.UserInfo SelectUser(string userName, string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"SELECT ID,UserName,Password,Email
FROM USERS WHERE UserName =@UserName AND Password = @Password ";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Password", password));
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();//创建数据库对象
Login.Model.UserInfo user = null;
while (reader.Read())//x循环读数据
{
if (user == null)
{
user = new Login.Model.UserInfo();
}
user.ID = reader.GetInt32(0);
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2);
if (!reader.IsDBNull(3))
{
user.Email = reader.GetString(3);
}
}
return user;
public class ScoreDAO
{
//
public void UpdateScore(string userName, int value)
{
//SqlConnection 表示一个到SQL的打开的连接
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();//表示要对 SQL Server 数据库执行的一个 Transact-SQL 语句或存储过程。
//实例化 一个 接口
cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values(@UserName,@Score)";
//获取或设置要对数据源要执行的Transact—SQL语句、表名、或存储过程
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
//增加两个参数将userName和Value的值赋给UserName和Score这两个占位符
conn.Open();
cmd.ExecuteNonQuery();
}
class DbUtil
{
public static string ConnString = @"Server = 晓;Database=Login;User ID=sa;Password = 123456";
//定义ConnString字符用来连接数据库 Server是自己的本机的名称 Database是数据库的名称
}
主要和数据库交互,SelectUser类根据从B层传进来的参数到数据库中查找相应的数据,然后放在reader中,然后在从reader中转移到一个新user的相应的属性中封装成一个新的user实体(此时和传进来的实体不一定相同),然后将封装好的新实体传回到B层进行逻辑判断。
小结
通过这个小例了解了一些三层的思想,这算是三层的一个见面礼吧,三层的思想主要是解耦,避免U层和D层直接交互,这样更有利于程序的扩展。而在三层之外的实体层避免了多个参数的传递,是程序更清晰。