.NET分层登陆——机房收费系统再总结
去年的时候,我写过一篇机房收费系统登陆的总结文章,那是站在VB的基础上,直接查询数据库实现的登陆。是非常初期的知识。假设想了解详情,请看VB查询数据库之登陆窗口——机房收费系统总结(一)。
今天。我要换一个角度。换一个方式。来实现登陆。首先,我选择的开发工具是VB.NET,数据库是SQLSever2008。
其次,我用的是三层的思想,把界面。逻辑和数据都分开。降低相互之间的影响。
在次。界面层尽量简洁。全部的算法和业务逻辑都写到逻辑层,同一时候使用了接口和工厂模式以及外观模式,降低了相互之间的依赖。降低了耦合。最后。通过文档和UML图。写出代码。实现登陆。
首先,看看我设计的登陆时序图(如有错误,欢迎指出。不胜感激):
看到图之后。假设你拥有一定的经验,相信对你来说,代码就不是问题了吧。以下,我把我的代码放在以下,仅供參考哦!(对了,U层界面没有变。假设想知道。请看连接博客)。
首先是实体层代码:
用户实体层:
Public Class UserInfoPrivate _userid As StringPrivate _password As StringPublic Property UserID As StringGetReturn _useridEnd GetSet(value As String)_userid = valueEnd SetEnd PropertyPublic Property PassWord As StringGetReturn _passwordEnd GetSet(ByVal value As String)_password = valueEnd SetEnd PropertyEnd Class 工作表实体层: <span style="font-size:18px;">Imports System Imports System.Data''' <summary> ''' 数据库表OpeLineRecord所相应的实体类 ''' </summary> Public Class OpeLineRecordEntityPrivate m_Opercomprecordid As StringPrivate m_Operatorid As StringPrivate m_Landdate As StringPrivate m_Landtime As StringPrivate m_Outdate As StringPrivate m_Outtime As StringPrivate m_Status As StringPrivate m_Computerid As StringPublic Sub OpeLineRecordEntity()m_Opercomprecordid = ""m_Operatorid = ""m_Landdate = ""m_Landtime = ""m_Outdate = ""m_Outtime = ""m_Status = ""m_Computerid = ""End Sub''' <summary>'''设置或返回值Opercomprecordid''' </summary>Public Property Opercomprecordid As StringGetReturn m_OpercomprecordidEnd GetSet(value As String)m_Opercomprecordid = valueEnd SetEnd Property''' <summary>'''设置或返回值Operatorid''' </summary>Public Property Operatorid As StringGetReturn m_OperatoridEnd GetSet(value As String)m_Operatorid = valueEnd SetEnd Property''' <summary>'''设置或返回值Landdate''' </summary>Public Property Landdate As StringGetReturn m_LanddateEnd GetSet(value As String)m_Landdate = valueEnd SetEnd Property''' <summary>'''设置或返回值Landtime''' </summary>Public Property Landtime As StringGetReturn m_LandtimeEnd GetSet(value As String)m_Landtime = valueEnd SetEnd Property''' <summary>'''设置或返回值Outdate''' </summary>Public Property Outdate As StringGetReturn m_OutdateEnd GetSet(value As String)m_Outdate = valueEnd SetEnd Property''' <summary>'''设置或返回值Outtime''' </summary>Public Property Outtime As StringGetReturn m_OuttimeEnd GetSet(value As String)m_Outtime = valueEnd SetEnd Property''' <summary>'''设置或返回值Status''' </summary>Public Property Status As StringGetReturn m_StatusEnd GetSet(value As String)m_Status = valueEnd SetEnd Property''' <summary>'''设置或返回值Computerid''' </summary>Public Property Computerid As StringGetReturn m_ComputeridEnd GetSet(value As String)m_Computerid = valueEnd SetEnd PropertyEnd Class</span> 将Datatable转换为泛型 <span style="font-size:18px;">Imports System.Collections.Generic '添加泛型的命名空间 Imports System.Reflection Public Class EntityHelperPublic Shared Function convertTolist(Of T As {New})(ByVal dt As DataTable) As IList(Of T) '将DataTable转化为泛型集合'注意:1,convertToList(Of T As {New} 这里的New是用来约束T的,必须有,不然new T 的时候会出现错误''2,new约束在C#和VB.NET里面的写法是不一样的。C#里面用的是where来为T加上约束的 Dim myList As New List(Of T) '定义终于返回的集合Dim myType As Type = GetType(T) '得到实体类的类型么Dim dr As DataRow '定义行集Dim tempName As String = String.Empty '定义一个暂时变量'遍历DataTable的全部数据行For Each dr In dt.RowsDim myT As New T '定义一个实体类的对象Dim propertys() As PropertyInfo = myT.GetType().GetProperties() '定义属性集合Dim Pr As PropertyInfo'遍历该对象的全部属性For Each Pr In propertystempName = Pr.Name '将属性名称赋值给暂时变量'检查DataTable是否包括此列(列名==对象的属性名)If (dt.Columns.Contains(tempName)) Then '将此属性与DataTable里的列名比較。查看DataTable是否包括此属性'推断此属性是否有SetterIf (Pr.CanWrite = False) Then '推断此属性是否可写,假设不可写,跳出本次循环Continue ForEnd IfDim value As Object = dr(tempName) '定义一个对象型的变量来保存列的值If (value.ToString <> DBNull.Value.ToString()) Then '假设非空。则赋给对象的属性Pr.SetValue(myT, value, Nothing) '在执行期间。通过反射,动态的訪问一个对象的属性End IfEnd IfNextmyList.Add(myT) '加入到集合NextReturn myList '返回实体集合End Function End Class </span>
然后是接口层IDAL:
<span style="font-size:18px;">Public Interface IUserFunction SelectUser(ByVal user As entity.UserInfo) As List(Of UserInfo)End Interface</span> D层:<span style="font-size:18px;">Imports IDAL Imports entity Imports System.Data.SqlClient Public Class UserDAL : Implements IDAL.IUserPublic Function SelectUser(user As UserInfo) As List(Of UserInfo) Implements IUser.SelectUserDim strUserID As String = user.UserIDDim helper As New Helper.SqlhelperDim dt As New DataTableDim mylist As List(Of UserInfo)Dim strSql As String = "select * from OperatorInfo where OperatorID=@UserID and state='使用'"Dim sqlParams As SqlParameter() = {New SqlParameter("@UserID", strUserID)} '声明并实例化參数dt = helper.ExecuteNonQuery(strSql, CommandType.Text, sqlParams) '调用SqlHelper类中的ExecSelect()方法来运行查询。并获取返回值mylist = EntityHelper.convertTolist(Of UserInfo)(dt) '将dt转换为泛型集合Return mylistEnd FunctionEnd Function End Class </span>
添加记录
<span style="font-size:18px;">Imports IDAL Imports entity Imports System.Data.SqlClient Public Class UserWorklogDAL : Implements IDAL.IUserWorklogPublic Function AddUserworklog(worklog As OpeLineRecordEntity) As Boolean Implements IUserWorklog.AddUserworklog'声明一个SqlHelper类型的helperDim helper As New Helper.SqlhelperDim dt As New Integer'声明并实例化须要运行的SQL语句Dim strSql As String = "Insert into OpeLineRecord (OperatorID,landDate,landTime,ComputerID,Status) values (@OperatorID,@landDate,@landTime,@ComputerID,@Status)"'声明兵实例化參数数组Dim sqlParams As SqlParameter() = {New SqlParameter("@OperatorID", worklog.Operatorid),New SqlParameter("@LandDate", worklog.Landdate),New SqlParameter("@LandTime", worklog.Landtime),New SqlParameter("@ComputerID", worklog.Computerid),New SqlParameter("@Status", worklog.Status)}'调用SqlHelper类中的ExecAddDeleteUser()方法来运行加入信息。获取返回值并Returndt = helper.ExecAddDelUpdate(strSql, CommandType.Text, sqlParams)Return dtIf dt > 0 ThenReturn TrueElseReturn FalseEnd IfEnd Function</span>外观:
<span style="font-size:18px;">Public Class LoginFACPublic Function Login(ByVal user As entity.UserInfo) As StringDim userlogin As New BLL.UserManageruserlogin.IsUserExit(user)If Not userlogin.IsUserExit(user) ThenThrow New Exception("password不对")End Ifuserlogin.CheckPWDIsRight(user)If userlogin.CheckPWDIsRight(user) = False ThenThrow New Exception("password不对")End If'推断用户是否登录了系统Dim userwork As New entity.OpeLineRecordEntityDim workbll As New BLL.UserWorklogManageruserwork.Operatorid = user.UserIDuserwork.Landdate = DateTime.Now.ToString("yyyy/MM/dd")userwork.Landtime = DateTime.Now.ToString("HH:mm")userwork.Computerid = System.Net.Dns.GetHostName()userwork.Status = "正在值班"'加入登录信息workbll.AddWorklog(userwork)End Function End Class</span>
SQLhelper层:
<span style="font-size:18px;">'通过配置文件获取连接字符串 Imports System.Data Imports System.Data.SqlClient 'Imports System.Configuration '加入对配置文件的引用Public Class Sqlhelper'调用配置文件 Private ReadOnly strConnection As String = Configuration.ConfigurationManager.AppSettings("ConnStr").ToString'有參数的查询'return DataTable 查询出的表格Public Function ExecuteNonQuery(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As DataTableUsing conn As New SqlConnection(strConnection) '使用连接池。能够在使用完毕后自己主动关闭连接Dim cmd As SqlCommand = conn.CreateCommand() 'Dim adp As SqlDataAdapterDim ds As New DataSetcmd.CommandText = cmdText '须要运行的SQL语句cmd.CommandType = cmdType '给出Sql语句的类型cmd.Parameters.AddRange(sqlParams) '參数数组,參数个数依据实际情况而定adp = New SqlDataAdapter(cmd)Tryconn.Open()adp.Fill(ds)'Return cmd.ExecuteNonQuery()Return ds.Tables(0)Catch ex As ExceptionReturn NothingThrow exEnd TryEnd UsingEnd Function'有參数的增删改Public Function ExecAddDelUpdate(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As IntegerUsing conn As New SqlConnection(strConnection)Dim cmd As SqlCommand = conn.CreateCommand()Dim adp As SqlDataAdapterDim ds As New DataSetcmd.CommandText = cmdTextcmd.CommandType = cmdTypecmd.Parameters.AddRange(sqlParams)adp = New SqlDataAdapter(cmd)Tryconn.Open()adp.Fill(ds)Return ds.Tables.CountCatch ex As ExceptionReturn NothingThrow exEnd TryEnd UsingEnd FunctionEnd Class </span> 工厂层:
B层:
加入上机记录
<span style="font-size:18px;">Imports Factory Imports entityPublic Class UserWorklogManagerPrivate ReadOnly factory As Factory.BDFactory = New Factory.BDFactoryDim iu As IDAL.IUserWorklog '声明并实例化变量iuser为:调用factory.CreateUserDAO()方法所返回来的IUser'加入用户工作记录Public Function AddWorklog(ByVal worklog As entity.OpeLineRecordEntity) As Booleaniu = factory.CreateUserworklogDAO()Dim dt As Integerdt = iu.AddUserworklog(worklog)If dt > 0 ThenReturn TrueElseReturn FalseEnd IfEnd Function </span> 查询用户是否存在 password是否正确<span style="font-size:18px;">Imports entity Public Class UserManagerPrivate ReadOnly factory As Factory.BDFactory = New Factory.BDFactory()Dim iuser As IDAL.IUserPublic Function IsUserExit(ByVal user As entity.UserInfo) As BooleanDim iu As IDAL.IUserDim mylist As List(Of UserInfo)iu = factory.CreateUserDAO()mylist = iu.SelectUser(user)If mylist.Count = 0 ThenReturn FalseElseReturn TrueEnd IfEnd FunctionPublic Function CheckPWDIsRight(ByVal user As entity.UserInfo) As BooleanDim iu As IDAL.IUserDim mylist As List(Of UserInfo)iu = factory.CreateUserDAO()mylist = iu.SelectUser(user)If Trim(mylist(0).PassWord) <> user.PassWord ThenThrow New Exception("输入password不对")Return FalseElseReturn TrueEnd IfEnd Function</span>最后是U层 <span style="font-size:18px;">Public Class frmloginPrivate Sub BtnOK_Click(sender As Object, e As EventArgs) Handles BtnOK.ClickDim user As New entity.UserInfo '实例化Useruser.UserID = txtUserName.Textuser.PassWord = txtPassword.TextIf txtUserName.Text.Trim().Length > 20 ThenMessageBox.Show("不能超过20位数字", "提示")Exit SubEnd IfIf txtUserName.Text.Trim() = "" ThenMessageBox.Show("请输入username", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)Exit SubElseIf txtPassword.Text.Trim() = "" ThenMessageBox.Show("请输入用password", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)Exit SubEnd IfTry'调用外观Dim loginfac As Facade.LoginFAC = New Facade.LoginFAC()loginfac.Login(user)Me.Hide()ForMain.Show()Catch ex As ExceptionMsgBox(ex.Message, CType(vbOKOnly + MsgBoxStyle.Information, MsgBoxStyle), "提示")End TryEnd SubEnd Class </span> Ok 系统结束,可能会有轻微的问题,细心就一定会解决(由于在粘贴的过程中,可能一不留神。你懂得……)。相对第一次来说,代码和逻辑上,并没有简单,并且反倒难了。那我们为什么还有继续呢?
不知道读者是否有这种疑问。事实上,非常easy,尽管代码和逻辑麻烦了,可是系统的性能更好了,逻辑也更清楚了,同一时候,降低了U层的负担。工作详细化。相同,兼容性扩展性更好了,健壮性也有所提高。更加适合合作开发。
这是一个小系统,假设是大系统,是不是优势就会更明显呢!
总结
以上是生活随笔为你收集整理的.NET分层登陆——机房收费系统再总结的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: CenterOS6.5 + OneinS
- 下一篇: 03-Windows Server 20