什么是三层?
物理上的三层:显示层/业务层/数据层
(客户PC;应用服务器;数据库服务器)
逻辑上的三层:UI BLL+DAL DB
我们讨论的三层结构:UI (显示层) BLL(业务逻辑层) DAL(数据访问层)
显示层
*UI的作用
1、向用户展现特定业务数据
2、采集用户的输入信息和操作
*UI的设计原则
用户至上,兼顾简洁
*UI中常用的技术
WindowsForm:Form、Control
ASP.NET:aspx、ascx、master、html
业务逻辑层
*BLL的作用
1、从DAL中获取数据,以供UI显示用
2、从UI中获取用户指令和数据,执行业务逻辑
3、从UI中获取用户指令和数据,通过DAL写入数据源
*BLL的职责机制
UI->BLL ->UI
UI->BLL ->DAL ->BLL->UI
数据访问层
*DAL的作用?(仅限于跟数据源打交道)
1、从数据源加载数据(Select)
2、向数据源写入数据(Insert、Update)
3、从数据源删除数据(Delete)
*DAL中常用的技术
1、ADO.NET+SQL语句
2、O/R Mapping框架 NHiberate
3、访问SQLSever数据库时Linq to SQL
什么情况下需要使用三层结构?
数据访问脱离业务单独存在,业务脱离开UI单独存在,UI只需要呼叫业务访问层和用户交互
三层具体应用–原则
*DAL只提供基本的数据访问,不包含任何业务相关的逻辑处理
*UI只负责显示和采集用户操作,不包含任何的业务相关的逻辑处理
*BLL负责处理业务逻辑。通过获取UI传来的操作指令,决定执行业务逻辑,在需要访问数据源的时候直接交给DAL处理,处理完成后,返回必要数据给UI
代码展示:
UI层:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
//获取输入的用户名和密码
string userName = txtUserName.Text.Trim();
string userPassword = txtPassword.Text;
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
//调用B层的登录方法,从B层返回user的信息
UserInfo user = mgr.Login(userName, userPassword);
MessageBox.Show("登录用户:" + user.UserName);
}
}
BLL层:
public class LoginManager
{
public UserInfo Login(string userName,string password)
{
//实例化UserDao
UserDAO uDao = new UserDAO();
//调用UserDao的查询用户方法
UserInfo user = uDao.SelectUser(userName, password);
//如果用户存在,就调用ScoreDao的更新积分方法,给用户加10积分;否则就抛出异常
if (user != null)
{
ScoreDAO sDao = new ScoreDAO();
//调用ScoreDao的更新积分方法
sDao.UpdateScore(userName, 10);
return user;
}
else
{
throw new Exception("登录失败。");
}
}
}
DAL层:
public class UserDAO
{
/// <summary>
/// 查询用户是否存在并返回用户信息
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <returns></returns>
public UserInfo SelectUser(string userName,string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();
//获取执行的SQL语句 或表名 或存储过程名
cmd.CommandText = @"SELECT ID,UserName,Password,Email
FROM USERS WHERE UserName=@UserName AND Password=@Password";
//指示执行的是存储过程还是sql语句,默认执行语句
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Password", password));
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
UserInfo user = null;
while (reader.Read())
{
if (user == null)
{
user = new 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
{
/// <summary>
/// 更新用户积分
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="value">要增长的积分</param>
public void UpdateScore(string userName,int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();
//查询Scores表中是否已有用户信息
cmd.CommandText = @"SELECT * FROM Scores WHERE UserName =@UserName";
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
//如果Scores表中用户积分已存在就在原来的基础上加10份;否则就插入新的用户积分数据
if (reader.Read())
{
//在用户原有积分基础上加10分
cmd.CommandText = @"UPDATE Scores SET Score+=10 WHERE UserName = @UserName";
//关闭reader
reader.Close();
//执行SQL语句
cmd.ExecuteNonQuery();
}
else
{
reader.Close();
//插入新的用户积分数据
cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values(@UserName,@Score)";
cmd.ExecuteNonQuery();
}
}
}
}
若有不足,欢迎指正