三层架构就是将整个业务应用划分为:显示层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的是为了“高内聚低耦合”。
系统比较容易迁移,业务逻辑层与数据访问层是分离的,修改数据访问层不会影响到业务逻辑层。系统如果从用SQL Server存储数据迁移到用Oracle存储数据,并不需要修改商业逻辑层组件和GUI组件。
数据访问层(DAL):
作用:从数据源加载数据(select),向数据源写入数据(insert/update),从数据源删除数据(delete)
技术:ADO.NET+SQL语句,O/R Mapping框架 NHiberate,访问SQL Server数据库时Linq to SQL
显示层(UI):
作用: 向用户展现特定业务数据;采集用户的输入信息和操作
原则:用户至上、兼顾简洁
技术:Windows Form:Form、Control;ASP.NET:aspx,ascx,master,html
业务逻辑层(BLL):
作用:从DAL中获取数据,以供UI显示用;从UI中获取用户指令和数据,执行业务逻辑;从UI中获取用户指令和数据,通过DAL写入数据源。
职责机制:UI-BLL-UI;UI-BLL-DAL-BLL-UI
实体层(Entity):
作用:主要存放数据库中表的字段。
层与层间调用关系为:UI->BLL->DAL,每一层都调用业务实体层。
UI层
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 mgr = new Login.BLL.LoginManager();//实例化BLL层LoginManager类
Login.Model.UserInfo user= mgr.UserLogin(userName, password);//将userName与password作为参数传到BLL层,并将返回的参数赋值给user
MessageBox.Show("登录用户:" + user.UserName);//登录成功
}
}
}
BLL层
namespace Login.BLL
{
public class LoginManager
{
public Login.Model.UserInfo UserLogin(string userName,string password)
{
Login.DAL.UserDAO uDAO = new Login.DAL.UserDAO();//实例化DAL层UserDAO类
Login.Model.UserInfo user= uDAO.SelectUser(userName, password);//将userName与password作为参数传给DAL层,并将返回的参数赋值给user
if (user!=null)//登录成功
{
Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();//实例化DAL层ScoreDAO类
sDao.UpdateScore(userName, 10);//调取DAL层中的UpdateScore方法,进行更新数据库
return user;//将user的值返回到UI层
}
else
{
throw new Exception("登录失败");//user值没有赋值成功,导致登录失败
}
}
}
}
DAL层
//UserDAO类
namespace Login.DAL
{
public class UserDAO
{
public Login.Model.UserInfo SelectUser(string userName,string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//实例化连接数据库字符串conn,using用来自动释放资源
{
SqlCommand cmd = conn.CreateCommand();//创建一个关联的SqlCommand对象,此对象包含connection连接的;连接完成,此时可以对数据库进行操作了。
cmd.CommandText = @"SELECT * FROM USERS WHERE UserName=@UserName AND Password=@Password"; //查询数据库的SQL语句
cmd.CommandType = CommandType.Text;//CommandType是SqlCommand的一个属性,声明命令对象执行形式为文本
cmd.Parameters.Add(new SqlParameter("@UserName", userName)); //添加参数到参数集,add里面的第一个参数是要添加的参数名,第二个参数是参数的数据类型.Parameters的作用就是把存储过程执行结束后得到的参数传到程序里
cmd.Parameters.Add(new SqlParameter("@Password", password));
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();//实例化SqlDataReader,用于从数据库中只读的方式读取数据
Login.Model.UserInfo user = null;//定义一个为null的UserInfo类型变量
while (reader.Read())//Read是SqlDataReader的方法,将数据阅读器移到结果集的下一行并读取该行,返回值为bool类型
{
if (user==null)//如果没有user的信息,就实例化一个为空的UserInfo
{
user = new Login.Model.UserInfo();
}
user.ID= reader.GetInt32(0);//从数据库中读取并赋值给user,并转换为相应的数据类型
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2);
if (!reader.IsDBNull(3))//Email可以为空,IsDBNull为SqlDataReader的一个方法,返回bool类型,若数据为空则返回true,反之返回false
{
user.Email = reader.GetString(3);
}
}
return user;//将user值返回到BLL层
}
}
}
}
//ScoreDAL类
namespace Login.DAL
{
public class ScoreDAO
{
public void UpdateScore(string userName,int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//实例化连接数据库字符串conn,using用来自动释放资源
{
SqlCommand cmd = conn.CreateCommand();//创建一个关联的SqlCommand对象,此对象包含connection连接的;连接完成,此时可以对数据库进行操作了。
cmd.CommandText = @"INSERT INTO SCORES(ID,UserName,Score) Values(1,@UserName,@Score)";//向scores表中添加一条记录
cmd.Parameters.Add(new SqlParameter("@UserName", userName));添加参数到参数集,add里面的第一个参数是要添加的参数名,第二个参数是参数的数据类型.Parameters的作用就是把存储过程执行结束后得到的参数传到程序里
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();//打开资源
cmd.ExecuteNonQuery();//执行命令对象的SQL语句,返回一个int 类型的变量,返回数据库操作之后影响的行数;用来验证对数据库进行增删改的情况。
}
}
}
}
//DbUtil类
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=MAX;Database=Login; User ID=sa;Password=123456";//连接数据库字符串
}
}
实体层
namespace Login.Model
{
public class UserInfo//user属性
{
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
}
三层架构是用UI层接收用户输入的数据,作为参数传递给BLL,如果涉及到访问数据再传递给DAL进行处理。将处理的结构再返回到BLL,再返回到UI。将UI与DAL进行解耦,实现了“高内聚低耦合”的思想。