實體層
我在這先簡單介紹一下實體層,這是一個處在“三界之外”的東西,它不屬于任何一層,但是任何一層都和它有關聯,為什麼會在三層中出現這麼一層呢?其實這一層就是在經典三層傳送資料的,避免三層之間的交叉調用,更好的解耦。也許有同學問那麼直接傳送變量參數不就完了嗎?當參數隻有一個或者兩個的時候看不出效果,但是當我的參數多的時候呢?比如我們傳送學生資訊,那麼我們就需要N個參數,那樣的程式是不能要的。
是以我們将這些參數封裝成一個實體,用get()和set()方法來操作,這樣就簡單多了,也更好的展現了面向對象的思想。我們可以簡單的了解實體為資料庫中的一張表,這樣了解不是錯的,但是當涉及到多個表的時候就傳回不了實體類了,需要基于視圖來建立實體類。那麼我們就可以将所有表的所有字段都放在這個實體類中,這說明我們可以根據自己的需要來建立自己的實體類,怎樣符合怎樣用就可以,沒有死規定。
下面來看一下這個小例子的架構:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyM0gDMwAzM3EzNwITM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
來看一下代碼的實作:
實體層代碼:
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 [email protected] 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層直接互動,這樣更有利于程式的擴充。而在三層之外的實體層避免了多個參數的傳遞,是程式更清晰。