引言:
大家都很清楚,去饭店吃饭,服务员只管接待客人,出事只管烹炒客人要的美食,采购员只管按客人需求采购肉、海鲜、蔬菜,他们各司其职、共同协作为客人提供美食。
三层的特点:
我们现在讲的三层架构,就是用这样工作的,他们三者中任何依着发生变化时都不会影响到其他两者的正常工作,so体现了三层的“高内聚,低耦合”的特点。
三层具体的描述:
从图中我们可以看到三层分别为:表达层(UI、用户界面层)、业务逻辑层(BLL)、数据访问层(DAL)。简单地说一下他们的作用:UI:为用户提供交互操作界面;BLL:负责关键业务的处理和数据传递;DAL:实现数据库访问。这里我就不多说了,因为大家在其他地方会看到很多更详细的说法,但总的来说,核心就是这个了。
下面看看他们之间的依赖关系:
简单解释一下,很简单,记住你的代码中所有的三层项目都会在一个解决方案中,应用关系是上面的关系就对了,之后会说代码的时候,就不说这个了。
搭建三层的步骤:
(1)搭建表达层(window)
(2)搭建业务逻辑层(类)
(3)搭建数据访问层(类)
(4)实现各层之间的相互依赖
从步骤上来讲都很好理解,但是我们都知道数据在各层之间表达需要定义,那么我们知道ADO.NET中有DataSet组件帮我们做这个工作,它是从数据园中检索到的数据在内存中的缓存,应用它回事数据结构暴露在业务逻辑层和表达层中,因此,我们引入了实体。
通过实体我们就更好的对数据进行绑定了。
ok,看看实体是怎样定义的:
三层的demo:
做过王继斌老师关于三层登陆的Demo的就很好理解了。其中他除了做了一个loginUI的介面,做了一个loginBLL和一个loginDAL还有一个是loginModel类,其中LoginModel就是实体类,它可以与UI、BLL、DAL进行双向的数据传输。下面举一个登陆的三层小例子:
UI:
namespace LoginUI0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
//IDbConnection conn = new SqlConnection();
//IDbCommand cmd = conn.CreateCommand();
//cmd.CommandText = "select UserName Form USERS WHERE......";
//cmd.ExecuteReader();
string userName = txtName.Text.Trim(); //给实体层传值
string password = txtPassword.Text;
Login.BLL.loginService mgr = new Login.BLL.loginService(); //实例化业务层
Login.Model .UserInfo user=mgr.UserLogin (userName, password); //实体层传来的值
MessageBox.Show("登陆用户:" + user.UserName);
}
}
}
BLL:
namespace Login.BLL
{
public class loginService
{
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.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
sDao.UpdataScore(userName, 10);
return user;
}
else
{
throw new Exception("登陆失败!"); //抛出错误
}
}
}
}
DAL:
连接数据库字段:
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=mx; Database=Login; User ID=sa; Password=123456";//连接数据库的字段
}
}
user表:
namespace Login.DAL
{
public class UserDAO
{
public Login.Model.UserInfo SelectUser(string userName, string password)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString)) //用了using关键字,可以不用关闭连接
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"SELECT ID,UserName,Password,Email FROM [dbo].[User] 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; //声明一个变量user,初始值为null,不指向任何内存空间
while (reader.Read())
{
if (user == null) //判断user是否为空
{
user = new Login.Model.UserInfo();
}
user.ID = reader.GetInt32(0); //获取ID列的32为整数值 ,赋值
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2);
if (!reader.IsDBNull(3))
{
user.Email = reader.GetString(3);
}
}
return user;
}
}
}
}
Score表:
namespace Login.DAL
{
public class ScoreDAO
{
public void UpdataScore(string userName,int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString)) //连接数据库
{
SqlCommand cmd =conn.CreateCommand(); //command类
cmd.CommandText = @"INSERT INTO Score(UserName,Score) Values(@UserName,@Scores)"; //插入列
cmd.Parameters.Add(new SqlParameter("@UserName", userName)); //增加属性
cmd.Parameters.Add(new SqlParameter("@Scores", value));
conn.Open();
cmd.ExecuteNonQuery(); //查询
}
}
}
}
Model:
namespace Login.Model
{
public class UserInfo //定义了4个属性
{
public int ID{get;set;}
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
}
代码就是这样的,具体怎么用,就进行重构机房,很多问题就会想明白了。