实体层
我在这先简单介绍一下实体层,这是一个处在“三界之外”的东西,它不属于任何一层,但是任何一层都和它有关联,为什么会在三层中出现这么一层呢?其实这一层就是在经典三层传送数据的,避免三层之间的交叉调用,更好的解耦。也许有同学问那么直接传送变量参数不就完了吗?当参数只有一个或者两个的时候看不出效果,但是当我的参数多的时候呢?比如我们传送学生信息,那么我们就需要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层直接交互,这样更有利于程序的扩展。而在三层之外的实体层避免了多个参数的传递,是程序更清晰。