三层结构分别是是显示层(UI),业务逻辑层(BLL),数据访问层(DAL)
一,数据访问层(DAL)
DAL只提供基本的数据访问,不包含任何业务相关的逻辑处理;
DAL的作用
从数据源加载数据(Select)
向数据源写入数据(Insert/Update)
从数据源删除数据(Delete)
DAL中常用的技术
ADO.NET+SQL语句
O/R Mapping框架 NHiberate
访问SQL Server数据库时Ling to SQL
二,显示层(UI)
UI只负责显示和采集用户操作,不包含任何的业务相关的逻辑处理;
UI的作用:
1.向用户展现特定业务数据
2.采集用户的输入信息和操作
UI设计的原则
用户至上,兼顾简洁。
UI中常用的技术
Windows Form: Form、Control
ASP.NET:aspx、ascx、master、html
三,业务逻辑层(BLL)
BLL负责处理业务逻辑。通过获取UI传来的操作指令,决定执行业务逻辑,在需要访问数据源的时候直接交给DAL处理。处理完成后,返回必要数据给UI。
BLL的作用
从DAL中获取数据, 以供UI显示用
从UI中获取用户指令和数据,执行业务逻辑
从UI中获取用户指令和数据,通过DAL写入数据源
BLL的职责机制
UI->BLL->UI
UI->BLL->DAL->BLL->UI
从DAL中获取数据, 以供UI显示用
从UI中获取用户指令和数据,执行业务逻辑
从UI中获取用户指令和数据,通过DAL写入数据源
BLL的职责机制
UI->BLL->UI
UI->BLL->DAL->BLL->UI
DAL/BLL/UI分别在不同的程序集中各个层之间的引用关系
UI ->BLL-> DAL
DAL所在程序集不引用BLL和UIBLL需要引用DAL
UI直接引用BLL,可能会间接引用DAL
下面是我实现三层的代码:
LoginBLL:
LoginManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//业务逻辑层
namespace Login.BLL
{
public class LoginManager
{
public Login.Model.UserInfo UserLogin(string userName, string password)
{
Login.DAL.UserDAO uDao = new Login.DAL.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;
}
else
{
throw new Exception("登陆失败。");
}
}
}
}
LoginDAL
DbUtil.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=DESKTOP-LHA7AS3; Database=Login; User ID=sa; Password =123456";
}
}
ScoreDAO.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
//数据访问层
namespace Login.DAL
{
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();
}
}
}
}
UserDAO.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
//数据访问层
namespace Login.DAL
{
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())
{
if (user == null)
{
user = new Login.Model.UserInfo();
}
reader.GetInt32(0);
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2);//not suggestion
if (!reader.IsDBNull(3))
{
user.Email = reader.GetString(3);
}
}
return user;
}
}
}
}
LoginUI
form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//显示层实现
namespace LoginUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
string userName = txtUserName.Text.Trim();
string password = txtPassword.Text;
Login.BLL.LoginManager mar = new Login.BLL.LoginManager();
Login.Model.UserInfo user = mar.UserLogin(userName,password);
MessageBox.Show("登陆用户:" + user.UserName);
}
private void label1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
LoginModel
为了防止相互引用,出现问题,出现了model这个类库,用来传输数据。
UserInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//为了在三层传输数据才会有Medel,独立于其他的层次,不会引用任何程序集。
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; }
}
}