三層架構,通常意義上的三層架構就是將整個業務應用劃分為:表現層(UI)、商務邏輯層(BLL)、資料訪問層(DAL)。區分層次的目的即為了“高內聚,低耦合”的思想。
一、英文拓展:
三層架構(3-Tier ASrchitecture)
表現層UI(User Interface)
商務邏輯層BLL(Business Logic Layer)
資料訪問層DAL(Data Access Layer)
二、各層作用解析:
1、DAL作用:
1)從資料來源載入資料Select
2)向資料來源寫入資料Insert/Update
3)從資料來源刪除資料Delete
2、UI的作用:
1)向使用者展現特定業務資料。
2)採集使用者的輸入資訊和操作。
3)特定的資料顯示給使用者
原則:使用者至上,介面簡潔明了
3、BLL的作用:
1)從DAL中擷取資料,供UI顯示用。
2)從UI中擷取使用者指令和資料,執行商務邏輯。
3)從UI中擷取使用者指令和資料,通過DAL寫入資料來源。
BLL的職責機制:
UI——BLL——UI
UI——BLL——DAL——BLL——UI
4、資料模型的引入:
為了避免三層之間的互相引用,所以出現Model,用於傳輸資料的,業務資料模型
三、系統登陸執行個體,步驟:
1、建立資料庫
(名稱)LoginDemo,包含兩張表:
建立表Users
其中,設定ID為主鍵,自增長。
建立表Scores
其中,設定ID為主鍵,自增長。
2、編碼階段:
解決方案名稱:LoginSolution
位置:LoginDemo
1)DAL資料訪問層:
建立項目名稱:LoginDAL
預設命名空間:Login.DAL
添加類:UserDAO,ScoreDAO,DbUtil
引用:LoginModel
namespace Login.DAL{ class DbUtil { //sever機器名,Database資料庫名, public static string ConnString = @"Server=192.168.**.**;Database=LoginDemo;User ID=sa;Password=123456"; }}//每成功登陸一次使用者,增加10點積分。 public class ScoreDAO { public void UpdateScore(string userName, int value) { using (SqlConnection conn = new SqlConnection(DbUtil.ConnString)) { SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values (@UserName,@Score)"; cmd.Parameters.Add(new SqlParameter("@UserName", userName)); cmd.Parameters.Add(new SqlParameter("@Score", value)); conn.Open(); cmd.ExecuteNonQuery(); } } }public class UserDAO { //根據userName和password返回一個布爾值。 public Login.Model.UserInfo SelectUser(string userName, string password) { { //有了using以後,connection就可以自動關閉 了 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(); //設定user的預設值為null Login.Model .UserInfo user=null; while (reader.Read()) { if (user==null ) { //如果user是null的話,則消極式載入 user=new Login .Model .UserInfo (); } user.ID=reader.GetInt32(0); user.UserName=reader.GetString(1); user.Password=reader.GetString(2);//not suggestion //如果Email不是null的話,才可以去讀。 if (!reader.IsDBNull(3)) { user.Email=reader.GetString(3); } } return user; } } } }
2)UI展示層:
添加新項目,Windows表單應用程式。
名稱:LoginUI ,設定為啟動項目
預設命名空間:Login.UI
引用:LoginBLL,LoginModel
登陸:btnLogin
使用者名稱:(Name):txtUserName
密碼: (Name):txtPassword; PasswordChar:*
表單: Text:系統登陸; MaximizeBox:False; MinimizeBox:False; FormBorderStyle:FixedSingle
namespace LoginUI{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnLogin_Click(object sender, EventArgs e) { ////通常,直接使用DAO呼叫資料庫。 //IDbConnection conn = new SqlConnection("c...."); //IDbCommand cmd = conn.CreateCommand(); //cmd.CommandText = "Select UserName From USERS WHERE ....."; //cmd.ExecuteReader(); //利用三層架構,需要引用下一層的 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 ); } }}
3)BLL商務邏輯層:
添加新項目;
名稱:LoginBLL
預設命名空間:Login.BLL
添加新類:LoginManager/LoginService服務
引用:LoginDAL,LoginModel
namespace Login.BLL{ public class LoginManager { public Login.Model.UserInfo UserLogin(string userName, string password) { //throw new NotImplementedException(); //呼叫資料來源,擷取相應資料 Login.DAL.UserDAO uDao = new Login.DAL.UserDAO(); Login.Model.UserInfo user = uDao.SelectUser(userName, password); if (user != null)//login successful { //如果登陸成功,則增加10點積分。 Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO(); sDao.UpdateScore(userName, 10); return user; } else { throw new Exception("登陸失敗。"); } } }}
4)Modle資料模型:
添加建立項目:
名稱:LoginModel
預設命名空間:Login.Model
添加類:UserInfo
Model資料模型:是獨立於其餘層次的,不知道其餘層次的資訊,其餘層次都會引用Model。介於UI和BLL,此處表示我們想要返回的資料為USER對象。
namespace Login.Model{ public class UserInfo { public int ID { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Email { get; set; } }}