万事开头难,是因为后面的学习差不多都是在开始定制的架构基础上填充的,填充的方法也是在开头上稍作修改实现的。所以说三层登录很不简单,在三层的基础上再加上外观层(Facade)、工厂层(Factory)、接口层(IDAL)就形成了七层。(再将SqlHelper单提取出来,就是传说中的八层了)。
首先根据包图设置好各层的调用。
再来说一下登陆的顺序和要做的工作。
再来看看各层的代码吧。
实体层:Entity层
实体层最容易了。被各层引用,进行数据传递。登录中用到两张表:UserInfo和WorkLog。所以就需要两个实体类:UserInfoEntity和WorkLogEntity,再加上一个公共变量类(里面包含正在登陆的用户名和密码)(代码就不做展示了)
SQLHelper
SQLHelper是数据库的小助手,被D层引用,用于一系列的数据库操作。只有一个类:Sqlhelper类,代码见SQLHelper类。
接口层:IDAL
接口层被B层和D层引用。提供了D层的对外接口,增加了灵活性。
IDAL-----IUserInfo
Public Interface IUserInfo
'查询用户
Function SelectUser(ByVal userinfoentity As Entity.UserInfoEntity) As List(Of Entity.UserInfoEntity)
'更改用户登录状态
Function UpdateUserStatus(ByVal userinfoentity As Entity.UserInfoEntity) As Boolean
End Interface
IDAL-----IWorkLog
Public Interface IWorkLog
'插入工作记录
Function InsertWorkLog(ByVal worklogentity As Entity.WorkLogEntity)
End Interface
数据访问层:D层
D层引用接口层、SQLHelper和实体层,实现IDAL层中的具体操作,对数据库进行增删改查,代码如下:
D层-----UserInfoDAL
'*************************************
'文件名:UserInfoDAL
'命名空间:DAL
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Imports System.Data.SqlClient
Imports System.Data
Public Class UserInfoDAL : Implements IDAL.IUserInfo
''' <summary>
''' 查询用户
''' </summary>
''' <param name="userinfoentity"></param>
''' <returns></returns>
''' <remarks></remarks>
'''
Function SelectUser(ByVal userinfoentity As Entity.UserInfoEntity) As List(Of Entity.UserInfoEntity) Implements IDAL.IUserInfo.SelectUser
Dim sql As New SQLHelper.SqlHelper
Dim dt As DataTable
Dim mylist As List(Of Entity.UserInfoEntity)
Dim sqlparams As SqlParameter() = {New SqlParameter("@UserID", userinfoentity.UserID),
New SqlParameter("@Password", userinfoentity.Password)}
Dim strsql As String = "Select * from UserInfo where UserID=@UserID and Password=@Password and IsUse='使用'"
dt = sql.ExecSelect(strsql, CommandType.Text, sqlparams)
mylist = ConvertHelper.convertToList(Of Entity.UserInfoEntity)(dt)
Return mylist
End Function
''' <summary>
''' 更改用户登录状态
''' </summary>
''' <param name="userinfoentity"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function UpdateUserStatus(ByVal userinfoentity As Entity.UserInfoEntity) As Boolean Implements IDAL.IUserInfo.UpdateUserStatus
Dim sql As New SQLHelper.SqlHelper
Dim dt As New Integer
Dim sqlparams As SqlParameter() = {New SqlParameter("@UserID", Entity.CommonVariable.strCurrentUserID),
New SqlParameter("@Status", "True")}
Dim strsql As String = "Update UserInfo set Status=@Status where UserID=@UserID"
dt = sql.ExecAddDelUpdate(strsql, CommandType.Text, sqlparams)
If dt > 0 Then
Return True
Else
Return False
End If
End Function
End Class
D层--------WorkLogDAL
'*************************************
'文件名:WorkLogDAL
'命名空间:DAL
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Imports System.Data.SqlClient
Imports System.Data
Public Class WorkLogDAL : Implements IDAL.IWorkLog
''' <summary>
''' 插入工作记录
''' </summary>
''' <param name="worklogentity"></param>
''' <returns></returns>
''' <remarks></remarks>
Function InsertWorkLog(ByVal worklogentity As Entity.WorkLogEntity) Implements IDAL.IWorkLog.InsertWorkLog
Dim sql As New SQLHelper.SqlHelper
Dim dt As Integer
worklogentity.LoginTime = Format(Now, "yyyy-MM-dd HH:mm:ss")
'声明并实例化参数数组
Dim sqlparams As SqlParameter() = {New SqlParameter("@UserID", Entity.CommonVariable.strCurrentUserID),
New SqlParameter("@Status", "正在值班"),
New SqlParameter("@LoginTime", worklogentity.LoginTime)}
Dim strsql As String = "Insert into WorkLog(UserID,LoginTime,Status)values(@UserID,@LoginTime,@Status)"
dt = sql.ExecAddDelUpdate(strsql, CommandType.Text, sqlparams)
If dt > 0 Then
Return True
Else
Return False
End If
End Function
End Class
D层-------ConvertHelper
该类用于DataTable转换为泛型,详见http://blog.csdn.net/u013036274/article/details/46462013
工厂层-----Factory层
Factory层被B层引用,引用接口层、实体层,创建接口。
'*************************************
'文件名:UserInfoFactory
'命名空间:Factory
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Imports System.Reflection '添加反射的引用
Imports IDAL
Imports System.Configuration
Public Class UserInfoFactory
Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
'用户工厂
Public Function CreateIUserInfo() As IUserInfo
Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & strDB), IUserInfo)
End Function
End Class
'*************************************
'文件名:WorkLogFactory
'命名空间:Factory
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Imports System.Reflection '添加反射的引用
Imports IDAL
Imports System.Configuration
Public Class WorkLogFactory
Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
'工作记录工厂
Public Function CreateIWorkLog() As IWorkLog
Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & strDB), IWorkLog)
End Function
End Class
业务逻辑层:B层
B层引用实体层、工厂层、接口层,被外观层引用,实例化工厂类、接口类,并且进行各种业务逻辑判断。
'*************************************
'文件名:LoginBLL
'命名空间:BLL
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Public Class LoginBLL
''' <summary>
''' 查询用户是否存在
''' </summary>
''' <param name="userinfoentity"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function IsUserOK(ByVal userinfoentity As Entity.UserInfoEntity) As List(Of Entity.UserInfoEntity)
Dim userinfofactory As New Factory.UserInfoFactory
Dim iuserinfo As IDAL.IUserInfo
Dim mylist As List(Of Entity.UserInfoEntity)
iuserinfo = userinfofactory.CreateIUserInfo()
mylist = iuserinfo.SelectUser(userinfoentity)
'判断是否查询到记录
If mylist.Count = 0 Then
Throw New Exception("登录失败,用户名和密码不正确!")
End If
If mylist(0).Status.Trim() = "True" Then
Throw New Exception("该用户正在登陆,请重新输入")
Else
MsgBox("登录成功,进入系统!")
End If
Return mylist
End Function
''' <summary>
''' 更改用户登录状态
''' </summary>
''' <param name="userinfoentity"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function ModifyUserStatus(ByVal userinfoentity As Entity.UserInfoEntity)
Dim dt As Integer
Dim userinfofactory As New Factory.UserInfoFactory
Dim iuserinfo As IDAL.IUserInfo
iuserinfo = userinfofactory.CreateIUserInfo()
dt = iuserinfo.UpdateUserStatus(userinfoentity)
If dt > 0 Then
Return True
Else
Return False
End If
End Function
''' <summary>
''' 插入工作记录
''' </summary>
''' <param name="worklogentity"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function AddWorkLog(ByVal worklogentity As Entity.WorkLogEntity)
Dim dt As Integer
Dim worklogfactory As New Factory.WorkLogFactory
Dim iworklog As IDAL.IWorkLog
iworklog = worklogfactory.CreateIWorkLog()
dt = iworklog.InsertWorkLog(worklogentity)
If dt > 0 Then
Return True
Else
Return False
End If
End Function
End Class
外观层:Facade层
外观层,被U层引用,应用实体层B层,进一步解耦U层和B层,为所有的逻辑判断等提供一个统一的界面,减少了U层繁杂的B层实例化。
'*************************************
'文件名:LoginFacade
'命名空间:Facade
'作者:郑艳霞
'小组:
'创建时间:
'版本号:v1.0
'修改时间:
'修改人:
'*************************************
Public Class LoginFacade
'判断用户和密码是否正确
Public Function IsUserOK(ByVal userinfoentity As Entity.UserInfoEntity) As List(Of Entity.UserInfoEntity)
Dim mylist As List(Of Entity.UserInfoEntity)
Dim loginbll As New BLL.LoginBLL
mylist = loginbll.IsUserOK(userinfoentity)
Return mylist
End Function
'更新用户工作状态
Public Function ModifyUserStatus(ByVal userinfoentity As Entity.UserInfoEntity)
Dim dt As Integer
Dim loginbll As New BLL.LoginBLL
dt = loginbll.ModifyUserStatus(userinfoentity)
Return dt
End Function
'添加工作记录
Public Function AddWorkLog(ByVal worklogentity As Entity.WorkLogEntity)
Dim dt As Integer
Dim loginbll As New BLL.LoginBLL
dt = loginbll.AddWorkLog(worklogentity)
Return dt
End Function
End Class
用户界面层:U层
U层,引用实体层、外观层,向外面向用户,向内面向外观层,并且进行数据的传递,App.config文件也写在U层。
Public Class frmLogin
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim userinfoentity As New Entity.UserInfoEntity '实例化UserInfoEntity
Dim worklogeneity As New Entity.WorkLogEntity '实例化WorkLogEntity
Dim loginfacade As New Facade.LoginFacade
Dim mylist As New List(Of Entity.UserInfoEntity)
'判断输入框是否为空
If txtUserID.Text = "" Then
MsgBox("用户名不能为空")
Return
End If
If txtPassword.Text = "" Then
MsgBox("密码不能为空")
Return
End If
Try
'将界面中的数据传给实体层
userinfoentity.UserID = txtUserID.Text.Trim()
userinfoentity.Password = txtPassword.Text.Trim()
'判断用户能否登录
mylist = loginfacade.IsUserOK(userinfoentity)
'将正在登录的用户登录信息传给全局变量
Entity.CommonVariable.strCurrentUserID = userinfoentity.UserID
Entity.CommonVariable.strCurrentPassword = userinfoentity.Password
'登录成功,更新用户的登录状态
loginfacade.ModifyUserStatus(userinfoentity)
'更新Worklog
loginfacade.AddWorkLog(worklogeneity)
'判断用户级别
Select Case mylist(0).Level.Trim()
Case "操作员"
frmMain.管理员ToolStripMenuItem.Visible = False
Case "一般用户"
frmMain.操作员ToolStripMenuItem.Visible = False
frmMain.管理员ToolStripMenuItem.Visible = False
End Select
frmMain.Show()
Me.Hide()
Catch ex As Exception
MsgBox(ex.Message.ToString())
txtUserID.Focus()
txtUserID.SelectAll()
txtPassword.Text = ""
End Try
End Sub
End Class
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DB" value="Sqlserver" />
<add key="strConnection" value="server=.;database=JF;UID=sa;PWD=123456" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
</configuration>
至此,七层完成。
小结:
理解了各层的关系和要做的工作,差不多七层的逻辑就出来了,登录时机房收费中最小的功能,但是却是最不简单的一步,登录清除了,各层的调用和关系就清楚了,一些对数据库的操作:增查也清楚了,后续功能的实现就简单多了。