剛開始接觸三層的時候沒頭緒,雖然知道它們之間的引用關系,可是還是感覺很混亂,所以上網看了看博客,決定先從畫圖入手。從包圖——>類圖——>時序圖(邏輯)——>代碼,一步步的重新做!

為什麼要有實體層?沒有實體層可以嗎?為什麼不叫四層,而叫三層呢?
實體層的作用是便於層與層之間數據的傳遞,每個實體對象與數據庫裡的表示一一對應的。對於大量的數據來說,就可以直接通過實體對象用Get(),Set()方法將字段提取出來,這比臨時在創建變量要省事。就相當於利用面向對象的思想,將大量的數據進行封裝後在進行傳遞。
例如:
AddUser(UserID,UserName,UserPassword)
用了實體層,將這些字段封裝到UserInfo類中,可以寫為AddUser(UserInfo),這樣就省事多了。
並不是一定要有實體層,如果只有少量數據, 例如機房收費系統中,查詢某個卡號對應的學生,可以通過CardID作為參數來進行傳遞,也就沒有必要用實體層進行傳遞了。
實體層是為了數據傳遞提供方便,只是一個類,並無實際作用,可有可無,所以不可以和UI,DAL,BLL一樣作為層來說。
1、實體層 UserInfo類

2、D層:DbUtil類和UserDAO類

3、B層:LoginManager類

4、U層:FrmLogin類


1、Entity層:UserInfo類
namespace LoginModel
{
//數據庫表的映射
public class UserInfo
{
private string username;
public string UserName
{
get { return username; }
set { username = value; }
}
private string password;
public string PassWord
{
get { return password; }
set { password = value; }
}
public UserInfo(string username, string password)
{
this.username = username;
this.password = password;
}
}
}
2、D層:
(1)DbUtil類:
namespace LoginDAL
{
///
/// 創建連接數據庫字符串
///
class DbUtil
{
public static string ConnString = @"server=bill\BILLSQL;dataBase=Users;user id=sa;password=123456";
}
}
(2)UserDAO類:
主要用於提供數據庫的基本訪問,供BLL調用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace LoginDAL
{
public class UserDAO
{
//查詢用戶
public LoginModel.UserInfo SelectUser(string username, string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//創建SQL數據庫打開連接
{
SqlCommand cmd = conn.CreateCommand(); //創建並返回一個與 SqlConnection 關聯的 SqlCommand 對象
cmd.CommandText = @"select username,password from user_Info where username=@username and password=@password";//獲取數據源執行的查詢語句
cmd.CommandType = CommandType.Text;//設置一個值用來解釋CommandText屬性
//將指定的SqlParameter添加到SqlParameterCollection中
cmd.Parameters.Add(new SqlParameter("@username", username));
cmd.Parameters.Add(new SqlParameter("@password", password));
conn.Open();//打開數據庫連接
SqlDataReader reader = cmd.ExecuteReader();//將 CommandText 發送到 Connection 並生成一個 SqlDataReader
LoginModel.UserInfo user = null;
//使 SqlDataReader 前進到下一條記錄
while (reader.Read())
{
if (user == null)
{
user = new LoginModel.UserInfo();
}
user.UserName = reader.GetString(0);
user.PassWord = reader.GetString(1);
}
return user;
}
}
}
}
3、B層:LoginManager類
處理業務邏輯,主要包括判斷用戶名與密碼的是否為空,以及從D層中獲取的數據傳遞給實體層。
namespace LoginBLL
{
public class LoginManager
{
public LoginModel.UserInfo UserLogin(string username, string password)
{
//throw new NotImplementedException();
LoginDAL.UserDAO uDAO = new LoginDAL.UserDAO();
//用戶名不能為空
if (username == null)
{
throw new Exception("請輸入用戶名");
}
//密碼不能為空
if (password == null)
{
throw new Exception("請輸入密碼");
}
LoginModel.UserInfo user = uDAO.SelectUser(username, password);
if (user != null)
{
return user;
}
else
{
throw new Exception("登錄失敗");
}
}
}
}
4、U層:FrmLogin類
主要是界面命令以及操作,接收B層傳來的數據。
namespace LoginUI
{
public partial class FrmLogin : Form
{
public FrmLogin()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
string username = txtUserName.Text.Trim() ;
string password = txtPassWord.Text;
try
{
LoginBLL.LoginManager mgr = new LoginBLL.LoginManager();
LoginModel.UserInfo user = mgr.UserLogin(username, password);
MessageBox.Show("登錄用戶:" + user.UserName);
}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}
}
private void btnCancel_Click(object sender, EventArgs e)//卸載窗體
{
Close();
}
}
}