.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
- 下一篇: [外文理解] DDD创始人Eric Va