一、实例讲解三层关系
今天给大家介绍一下三层架构,到底什么是三层架构?它既然存在,存在的必要是什么呢?下面我们以实例图为导向,展开我们今天的学习。
三层架构由三部分构成,分别为UI(界面层)、BLL(业务逻辑层)、DAL(数据访问层)
UI表示层(User Interface):
提供一个界面,实现与用户的交互,很好理解。例如登录界面,接收并处理用户的数据。
BLL业务逻辑层(Business Logic Layer):
是UI 与DAL层交互的桥梁,对数据进行业务逻辑操作。
例如,验证用户输入的是否正确,如果正确提供给用户一些奖励,实施具体的运算,服务员核查客户是否点了某一道菜,如果点了,将美食反馈给用户一样。
DAL数据访问层(Data Access Layer):
访问数据库中数据,与数据库存在联系,主要实现对数据的增、删、改、查。并将数据传递给业务层,以及将业务逻辑层处理好的数据保存到数据库。
解析:厨师只做饭,什么都不需要做(谁都不引用)
服务员需要获取厨师做好的饭(BLL引用DAL)
客户找服务员要饭吃(UI直接引用BLL)
各个层次之间的关系:UI→BLL→DAL(→表示引用)U层也间接的引用了D层。
二、具体代码实现
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; //获取密码,有可能password是个空格所有就不用TRim了
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager(); //实例化B层,用户需要和服务员交流了,服务员要去干活了。
Login.Model.UserInfo user = mgr.UserLogin(userName, password);//将用户输入的用户名和密码赋值给Model实体,
MessageBox.Show("登陆用户:" + user.UserName);
}
}
}
BLL层
namespace Login.BLL
{
public class LoginManager
{
public Login.Model.UserInfo UserLogin(string userName,string password)//获取用户的传输指令
{
//业务层需要引用数据访问层,实例化我们的厨师,用户的信息到达D层,开始去D层走代码了。
Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();
//将访问到的数据赋值给Model,进行对比,检查是否一致
Login.Model.UserInfo user = uDao.SelectUser(userName, password);
if (user != null)//如果有这个用户就走if的语句
{
Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
sDao.UpdateScore(userName, 10); //进行加分到数据库Scores表中
return user;
}
else //如果没有就显示登陆失败
{
throw new Exception("登陆失败");
}
}
}
}
DAL层
namespace Login.DAL
{
public class UserDAO
{
public Login.Model.UserInfo SelectUser(string userName,string password)
{
//实例化SqlConnection
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))
{
SqlCommand cmd = conn.CreateCommand();//cmd是执行sql指令的
cmd.CommandText = @"SELECT ID,UserName,password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password";
//CommandType是SqlCommand的一个属性,它用来告诉接下来执行的是一个文本
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));//传值
cmd.Parameters.Add(new SqlParameter("@Password", password));//同上
conn.Open();//打开数据库
//ExecuteReader尽可能快的对数据库进行查询并得到结果
SqlDataReader reader = cmd.ExecuteReader();
//初始值为空
Login.Model.UserInfo user = null;
while (reader.Read())
{
if (user == null)
{
user = new Login.Model.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;
}
}
}
}
加分类
vnamespace Login.DAL
{
//加分类
public class ScoreDAO
{
public void UpdateScore(string userName,int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//自动释放垃圾,避免资源浪费
{
SqlCommand cmd = conn.CreateCommand();//实例cmd来执行下边的sql语句
cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values(@UserName,@Score)";//插入数据到scores表中
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();
//ExecuteNonQuery()方法主要用于用户更新
cmd.ExecuteNonQuery();
}
}
}
}
Eneity实体类
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; }
}
}
总结
在学习的过程中遇到很多的小问题不能实现最终的效果,总以为是视频中有遗漏没有做的地方不动脑子的采用最笨的方法去找错误,最后还是使用了走代码的形式一条条的检查,这样让我对代码的理解加深了还对他们的关系有了深一步的理解。这个项目虽然东西不多但感觉成长了很多。
期待后面的重构~