VB.NET版机房收费系统之七层登录
七层UML图 七层登录是在三层登录的基础上加了外观模式,抽象工厂模式+反射+配置文件,接口和SQLHelper。开始之所以学习七层登录,是因为登录模块比较简单,通过简单的例子学习和理解七层架构的优势所在。先易后难,逐步提高。
各层之间的引用关系:
实现步骤: 1、创建Entity,实现业务实体。
七层具体展示: UI层(作用:U层负责数据的录入与输出。在U层,先通过调用U层中的验证用户类的验证方法来确认所输入用户是否合法,然后通过调用Fa?ade层验证用户类的查询方法来确认该用户是否存在。)
Public Class FrmLogin
Private Sub btnOK_Click(sender As Object,e As EventArgs) Handles btnOK.Click
'判断输入不能为空
If txtUserName.Text = "" Then
MsgBox("请输入用户名",MessageBoxButtons.OK,MessageBoxIcon.Exclamation)
txtUserName.Focus()
End If
'If IsNumeric(txtUserName.Text) = False Then
If txtPassword.Text = "" Then
MsgBox("请输入密码",MessageBoxIcon.Exclamation)
txtPassword.Focus()
End If
Entity.LoginEntity.ID = txtUserName.Text.Trim
Dim Facade As New Facade.LoginFacade '定义一个外观对象
Dim UserInfo As New Entity.LoginEntity
UserInfo.UserID = txtUserName.Text.Trim
UserInfo.Password = txtPassword.Text
Dim strResult As Boolean
'将U层的用户信息传入外观层,然后通过外观层传入B层进行判断
strResult = Facade.CheckUser(UserInfo)
If strResult = False Then
MsgBox("用户不存在")
txtUserName.Text = ""
txtUserName.Select()
txtUserName.Focus()
End If
Dim table As DataTable
table = Facade.CheckPwd(UserInfo)
If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(1)) Then
Me.Hide()
FrmMain.Show()
Else
MsgBox("密码不正确")
txtPassword.Text = ""
txtPassword.Select()
txtPassword.Focus()
End If
End Sub
Public Class LoginFacade '检查用户是否存在 Public Function CheckUser(ByVal UserInfo As Entity.LoginEntity) As Boolean Dim IsUserExists As New BLL.LoginBLL Dim flag As Boolean flag = IsUserExists.ExistUser(UserInfo) If flag = True Then Return True Else Return False End If End Function '检查密码是否正确 Public Function CheckPwd(ByVal UserInfo As Entity.LoginEntity) As DataTable Dim IsPwdExists As New BLL.LoginBLL Dim table As DataTable table = IsPwdExists.RightPWD(UserInfo) Return table End Function End Class
Public Class LoginBLL '检查用户是否存在 Public Function ExistUser(ByVal UserInfo As Entity.LoginEntity) As Boolean Dim Factory As New Factory.LoginFactory Dim IUser As IDAL.LoginIDAL '调用创建用户的工厂方法 IUser = Factory.CreateIUser() '调用工厂的CreatIUser方法创建IUser接口实例 Dim table As New DataTable '中间变量,用于存储D层查询到的数据 Dim flag As Boolean table = IUser.selectUser(UserInfo) If table.Rows.Count = 0 Then flag = False Else flag = True End If Return flag End Function '查看密码是否正确 Public Function RightPWD(ByVal UserInfo As Entity.LoginEntity) As DataTable Dim Factory As New Factory.LoginFactory Dim IUser As IDAL.LoginIDAL Dim table As DataTable '中间变量,用于存储D层查询到的数据 Dim flag As Boolean IUser = Factory.CreateIUser '调用工厂的方法创建Iuser table = IUser.selectUser(UserInfo) '调用接口的方法selectUser 'If UserInfo.Password = Trim(table.Rows(0).Item(1)) Then Return table End Function End Class Factory层(作用:工厂层的主要作用是应用配置文件和反射技术实现数据库的更换功能。在Factory层中首先定义程序集的名字和明明空间的名字,将程序集的名字和命名空间的值写在配置文件中,当执行到Factory函数时程序会自动通过读取配置文件中的相应字符,按照路径实例化出相应的对象。) Imports System.Configuration '添加对配置文件的引用 Imports System.Reflection '添加对反射的引用 Imports IDAL '反射+配置文件+抽象工厂实现数据访问 Public Class LoginFactory Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称&命名空间DAL Dim strDB As String = System.Configuration.ConfigurationManager.AppSettings("DB") '于配置文件相连 Public Function CreateIUser() As LoginIDAL 'Dim classname As String = "DAL." + "LoginDAL" '要实例化的D层的类的名称 Dim IUser As LoginIDAL 'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果 Dim className As String = AssemblyName + "." + "LoginDAL" '如果要更改数据库,D层相应的类要提前写好 IUser = CType(Assembly.Load(AssemblyName).CreateInstance(className),IDAL.LoginIDAL) Return IUser End Function End Class IDAL层(作用:IDAL层中主要放置接口函数)
Public Interface LoginIDAL '判断用户名是否存在 Function selectUser(ByVal UserInfo As Entity.LoginEntity) As DataTable End Interface DAL层(作用:实现接口中的方法并调用SqlHelper中的方法)
Imports System.Data.SqlClient 'system.Data.SqlClient 命名空间是SQLSever的.NET Framework数据提供程序 'SQL Sever 的.NET Framework数据提供程序描述了一个类集合,这个类集合用于访问托管空间中的SQL Sever数据库 Public Class LoginDAL : Implements LoginIDAL '实现接口中的方法 Private sqlHelper As New SQLHelper.sqlHelper '判断用户名是否存在 Public Function selectUser(UserInfo As Entity.LoginEntity) As DataTable Implements LoginIDAL.selectUser Dim sql As String '中间变量,用于储存从数据库中查找到的信息 Dim table As DataTable '声明一个DataTable '声明并实例化参数数组 Dim sqlParams As SqlParameter() = {New SqlParameter("@UserID",UserInfo.UserID),New SqlParameter("@Password",UserInfo.Password)} sql = "select * from User_Info where UserID=@userID and PWD=@Password" '调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值 table = sqlHelper.ExecSelect(sql,CommandType.Text,sqlParams) Return table End Function End Class SqlHelper层(作用:执行增删改查等功能,sqlhelper中的主要函数包括获得执行带参数和不带参数的非查询功能,执行带参数的和不带参数的获取datatable的查询功能,获取带参数的和不带参数的获得一个阅读器的查询功能) Imports System.Data.SqlClient Imports System.Configuration '添加对配置文件的引用 Imports System.Reflection '添加对反射的引用 Public Class sqlHelper '数据库连接 Dim strConnection As String = ConfigurationManager.AppSettings("DB") Dim conn As New SqlConnection(strConnection) Dim cmd As New SqlCommand Public Function ExecSelect(ByVal cmdText As String,ByVal cmdType As CommandType,ByVal paras As SqlParameter()) As DataTable Dim sqlAdapter As SqlDataAdapter '定义数据适配器 Dim dt As New DataTable Dim ds As New DataSet '给cmd 赋值 cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = conn cmd.Parameters.AddRange(paras) '添加参数 sqlAdapter = New SqlDataAdapter(cmd) '实例化Adapter Try sqlAdapter.Fill(ds) '用adapter将dataset填充 dt = ds.Tables(0) 'datatable是dataset的第一个表 cmd.Parameters.Clear() '清除参数 Catch ex As Exception MsgBox("数据库操作") Finally Call CloseCmd(cmd) '关闭cmd命令 End Try Return dt End Function Public Sub CloseCmd(ByVal cmd As SqlCommand) If Not IsNothing(cmd) Then '如果cmd存在 cmd.Dispose() '销毁 cmd = Nothing End If End Sub End Class Entity实体(作用:设置各个参数的属性,在各层之间传递)
Public Class LoginEntity Public Shared ID As String '用于记录登录时的用户名 Private _UserID As String Public Property UserID As String Get Return _UserID End Get Set(value As String) _UserID = value End Set End Property Private _password As String Public Property Password As String Get Return _password End Get Set(value As String) _password = value End Set End Property End Class 遇到的问题: 在调试的过程中遇到下面这个问题。
解决方法:右击D层-属性-生成-输出路径-点击浏览改到U层的Bin里边即可
通过这个错误学到一个很重要的知识: .net类加载的机制就是默认从本程序集的bin文件中找,所以bin文件夹中一定要有要加载的程序集的dll)。UI层中bin文件夹中dll叫什么名字AssemblyPath就使用什么名字,bin内部类的全名叫什么,className就写成什么全名。.net中的引用:加入对某个程序集的引用就能在程序集有变化时自动拷贝dll。 小结: 七层登录实现了,可是这只是开始的第一步,下面的重构才是真正学东西的环节。我要加油! 关于反射+配置文件,在下一篇博客介绍。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |