万事开头难,是因为后面的学习差不多都是在开始定制的架构基础上填充的,填充的方法也是在开头上稍作修改实现的。所以说三层登录很不简单,在三层的基础上再加上外观层(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 InterfaceIDAL-----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 ClassD层--------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 ClassD层-------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>至此,七层完成。
小结:
理解了各层的关系和要做的工作,差不多七层的逻辑就出来了,登录时机房收费中最小的功能,但是却是最不简单的一步,登录清除了,各层的调用和关系就清楚了,一些对数据库的操作:增查也清楚了,后续功能的实现就简单多了。