先介绍一下三层的机制和原则,如下:
职责机制
UI(提出请求)——BLL(判断是否有能力,有能力)—— UI
UI—— BLL ——DAL (数据源访问,处理加工)——BLL(得到结果返回)——UI
原则:
Dal只提供基本单一的数据访问,不包含任何业务逻辑处理,不能分割的操作
UI只负责显示、采集用户操作,不包含业务相关逻辑处理
画面、输入的传给业务逻辑层,要数据;基础数据,加工的对象拿来
Bll处理业务逻辑,获取UI传来的操作指令,决定执行业务逻辑,在需要访问数据源的时候直接交给dal处理,处理完成后返回必要数据给UI
业务数据模型:
在这里设置属性,我把他理解成是一个基础,里面可以添加我们机房所需要的学号、姓名、密码、时间等等。这这里添加了之后我们才能使用,进而编写代码。
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">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; }
}
}
</span></span>
这是登录界面。
显示层UI/View请求方:
顾名思义,这是一个窗口,在以后的机房里重要是传用户名、密码给BLL业务逻辑层,之后再返回来判断的结果,有该用户则登录成功,如果没有该用户则在BLL业务逻辑层抛出错误,在这里我想着用Messagebox.show但是没有实现,这个之后再研究吧。
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">public partial class FrmLogin : Form
{
public FrmLogin()//登录界面实现
{
InitializeComponent();
}
private void BtnLogin_Click(object sender, EventArgs e)
{
//UI层文本框获得数据传给实体类中的参数
string userName = txtName.Text.Trim();
string password = txtPassWord.Text;
//初始化bll层中loginmanager类
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
//username和password传导B层,B层返回user到U层
Login.Model.UserInfo user = mgr.UserLogin(userName, password);
MessageBox.Show("登录用户" + user.UserName );
}
}</span></span>
业务逻辑层BLL的DbUtill.cs:
连接数据库,短小精悍的代码。
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">namespace Login.DAL
{
class DbUtill
{
//为了说明结构三层
//连接字符串 server机器名、database数据库名,用户名,密码
public static string ConnString = @"Server=Phoebe;Database=Login;User ID=sa;Password=mjx";//uid= sa;pwd=mjx";
}
}</span></span>
业务逻辑层BLL
在这里进行具体的业务逻辑判断,在这里调用DAL数据访问层UserDAO判断是否有该用户,如果有则调用ScoreDAO给该用户增加value积分,如果没有则抛出错误。相同的逻辑,机房中其他的判断比如金额是否充足等都可以在这里进行判断。
<span style="font-family:FangSong_GB2312;font-size:18px;">namespace Login.BLL//业务逻辑层实现
{
public class LoginManager
{
//从UI传来的指令(Userlogin),传来的数据(参数)
public Login.Model .UserInfo UserLogin(string userName,string password)
{
//实现业务逻辑
//throw new NotImplementedException();不实现
//呼叫数据源,跟数据源打交道
Login.DAL .UserDAO UDao= new Login.DAL.UserDAO();//构造UserDAO实例
//返回model.userindo,获取信息
Login .Model .UserInfo user= UDao.SelectUser(userName, password);
//业务逻辑,业务逻辑、业务逻辑、成功了怎么办,失败了怎么办
if (user !=null )
{
//登录成功
//增加积分,分工明确DAO
Login.DAL.ScoreDAO SDao = new Login.DAL.ScoreDAO();
SDao.UpdateScore(userName, 10);//增加积分10
return user;
}
else
{
throw new Exception("登录失败");
}
}
}</span>
数据访问层UserDAO
这里主要是执行SQL语句,读取Users表中信息,然后返回。有一个不太理解的地方:
设置:Login.Model.UserInfo user = null;之后user不就自然是“null”吗?之后为什么要再次判断“user”是否为空呢?请大家多多指教。
<span style="font-family:FangSong_GB2312;font-size:18px;"> <span style="font-weight: normal;">public Login.Model .UserInfo SelectUser(string userName,string password)
{
//具体业务
//得到connectionstring
//using后connection自动关闭
using ( SqlConnection conn = new SqlConnection(DbUtill.ConnString))//连接数据库
{
//cmd为命令对象(即SqlCommand),conn为连接对象(保持打开状态)
SqlCommand cmd = conn.CreateCommand();
//设置cmd命令文本,从表中选择***
cmd.CommandText = @"SELECT ID,UserName,Password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password";
cmd.CommandType = CommandType.Text; //执行SQL语句
//添加参数 Parameters:参数
cmd.Parameters .Add (new SqlParameter ("@UserName",userName ));
cmd.Parameters .Add (new SqlParameter ("@Password",password ));
conn.Open();//开启
//若要创建 SqlDataReader,必须调用 SqlCommand 对象的 ExecuteReader 方法
//ExecuteReader:返回sqlDatareader对象(数据读取器)
//该对象包含由某一命令返回的结果集
SqlDataReader reader = cmd.ExecuteReader();
Login.Model.UserInfo user = null;
//读取基本数据,调用数据读取器的Read()方法来判断是否有数据
while (reader .Read ())
{
if(user ==null)
{
user = new Login.Model.UserInfo();
}
//从数据库中提取:ID、UserName
user.ID = reader.GetInt32(0);
user.UserName = reader.GetString(1);
//密码不需要从数据库提取的
user.PassWord = reader.GetString(2);//not suggest
if (!reader .IsDBNull (3))
{
//如果邮箱不为空
user.Email = reader.GetString(3);
}
}
return user;//为数据库中的user,无则返回为null
}
}</span></span>
数据访问层的ScoreDAO
添加参数,执行SQL语句。
<span style="font-family:FangSong_GB2312;font-size:18px;"> public void UpdateScore(string userName,int value)
{
using (SqlConnection conn=new SqlConnection (DbUtill .ConnString ))//连接数据库
{
//利用一个现有连接创建一个Command,用以执行sql指令
SqlCommand cmd = conn.CreateCommand();
//values少加了一个;SCORE多了一个s;commandtext设置cmd的命令文本
cmd.CommandText = @"INSERT INTO SCORE (UserName,Score)Values(@UserName,@Score)";
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();//开启
//ExecuteNonQuery用于数据库更新,增加一条记录,
//返回值为1,1到BLL层,然后BLL层将数值1返回到UI层
cmd.ExecuteNonQuery();//执行sql语句
}
}</span>
有理解不对的地方,请大家不吝赐教,共同交流、一起进步,加油。