三层架构,通常意义上的三层架构就是将整个业务应用划分为:表现层(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; } } }