这几天开始进行登录窗体的三层转七层,自己是各种不会做,中间出现了各种问题,但是经过小伙伴们的帮助完美的实现了我的三层转七层。过程就不一一介绍了,下面咱们来讲讲七层。
七层包括:表现层(UI)、外观层(Facade)、业务逻辑层(BLL)、接口层(IDAL)数据访问层(DAL)、工厂层(Factory)和实体层(Entity)如下图:
SqlHelper类用于通过一组静态方法来封装数据访问功能。该类不能被继承或实例化,因此将其声明为包含专用构造函数的不可继承类。在SqlHelper类中实现的每种方法都提供了一组一致的重载。这提供了一种很好的使用 SqlHelper类来执行命令的模式,同时为开发人员选择访问数据的方式提供了必要的灵活性。每种方法的重载都支持不同的方法参数,因此开发人员可以确定传递连接、事务和参数信息的方式。
其实说了一大堆我认为Sqlhelper其实就是封装一个方法,通过返回值来完成对数据库的更改和查询。下面说一下我在机房收费系统中用到的sqlhelper。因为我在机房收费系统中只有涉及到一个数据库(多个表),所以sqlhelper通过SQL参数传递即可连接数据库实现查询。
下面来看一下我的七层框架实现的登录窗体
UI层:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'输入不能为空
If txtUserName.Text = "" Then
MsgBox("请输入用户名", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUserName.Focus()
End If
If IsNumeric(txtUserName.Text) = False Then
MsgBox("用户名请输入数字", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUserName.Text = ""
End If
If txtPassword.Text = "" Then
MsgBox("请输入密码", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtPassword.Focus()
End If
Try
Dim Facade As New Facade.LoginFacade
Dim UserInfo As New Entity.UserInfo
UserInfo.UserID = txtUserName.Text.Trim
UserInfo.Password = txtPassword.Text
Dim strResult As Boolean
'将U层的用户信息传入外观层,然后通过外观层传入B层进行判断
strResult = Facade.CheckUser(UserInfo)
If strResult = False Then
MsgBox("用户不存在", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUserName.Text = ""
txtPassword.Text = ""
txtUserName.Select()
txtUserName.Focus()
Else
Dim table As DataTable
table = Facade.CheckPwd(UserInfo)
If Trim(txtPassword.Text) = Trim(table.Rows(0).Item(1)) Then
MsgBox("登陆成功!")
Me.Hide()
FrmMain.Show()
txtPassword.Text = ""
txtUserName.Text = ""
Else
MsgBox("密码错误")
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
txtPassword.Text = ""
txtUserName.Text = ""
txtUserName.Select()
txtUserName.Focus()
End Try
End Sub
BLL层
Public Function Checkuser(ByVal UserInfo As Entity.UserInfo) As Boolean
Dim Fa As New Factory.LoginFactory
Dim IUser As IDAL.LoginIUserInfo
'调用创建用户的工厂方法
IUser = Fa.CreateIUser() '调用工厂的CreateIUser方法创建Iuser接口实例
Dim table As New DataTable
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 Checkpwd(ByVal UserInfo As Entity.UserInfo) As DataTable
Dim Factory As New Factory.LoginFactory
Dim IUser As IDAL.LoginIUserInfo
Dim table As DataTable
IUser = Factory.CreateIUser
table = IUser.selectUser(UserInfo)
Return table
End Function
Facade层
'外观层主要是对方法的封装,但还是调用的B层的方法,不过让数据在外观层走一遍。
Public Class LoginFacade
'检查用户是否存在
Public Function CheckUser(ByVal UserInfo As Entity.UserInfo) As Boolean
Dim IsUserExists As New BLL.LoginBll
Dim flag As Boolean
flag = IsUserExists.Checkuser(UserInfo)
If flag = True Then
Return True
Else
Return False
End If
End Function
'检查密码是否正确
Public Function CheckPwd(ByVal UserInfo As Entity.UserInfo) As DataTable
Dim IsPwdExists As New BLL.LoginBll
Dim table As DataTable
table = IsPwdExists.Checkpwd(UserInfo)
Return table
End Function
End Class
IDAL层
Public Interface LoginIUserInfo
'判断用户名是否存在
Function selectUser(ByVal UserInfo As Entity.UserInfo) As DataTable
End Interface
Factory层
'通过读取配置文件, 在以后更换数据库的时候, 只需要增加一个新的类, 而不需要修改原来的代码。
Imports System.Reflection '添加对反射的引用
Imports System.Configuration '添加对配置文件的引用
Imports System.Data
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 LoginIUserInfo
Dim classname As String = strDB + "." + "LoginDAL" '要实例化D层的类的名称
Dim IUser As LoginIUserInfo
'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果
IUser = CType(Assembly.Load(AssemblyName).CreateInstance(classname), LoginIUserInfo)
Return IUser
End Function
End Class
DAL层
Imports System.Data.SqlClient
Imports IDAL
Public Class LoginDAL : Implements IDAL.LoginIUserInfo
'实现接口中的方法
Private sqlHelper As New SqlHelper.sqlhelper
'判断用户名是否存在
Public Function selectUser(UserInfo As Entity.UserInfo) As DataTable Implements LoginIUserInfo.selectUser
Dim sql As String '中间变量,用于储存从数据库中查找到的信息
'声明并实例化参数数组
Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserID), New SqlParameter("@Password", UserInfo.Password)}
sql = "select * from User_info where UserID=@UserName and PWD=@Password"
Dim table As DataTable '声明一个dat
'调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值
table = sqlHelper.ExecSelect(sql, CommandType.Text, sqlParams)
Return table
End Function
End Class
SqlHelper层
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Public Class sqlhelper
'配置文件
'Private ReadOnly strConnection As String = ConfigurationSettings.AppSettings("ConnStr")
'数据库连接
Dim strConnection As String = "Server=192.168.24.193;Database=charge_sys;User ID=sa;Password=1"
Dim conn As New SqlConnection(strConnection) '设置连接
Dim cmd As New SqlCommand '设置命令
'有参数的查询操作
''' <summary>
'''
''' </summary>
''' <param name="cmdText">需要执行的命令</param>
''' <param name="cmdType">所执行命令的类型。一般是Sql语句,也有可能是存储过程,或表</param>
''' <param name="paras">参数数组</param>
''' <returns>返回执行 查询 得到的结果,为DataTable类型</returns>
'''
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.CommandText = cmdText '设置查询的语句
cmd.CommandType = cmdType '设置一个值,解释cmdText
cmd.Connection = conn '设置连接
cmd.Parameters.AddRange(paras) '将传入的值,分别为cmd的属性赋值
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
'每次数据库关闭之后都要关闭连接和命令
Private Sub CloseConn(ByVal conn As SqlConnection)
'如果没有关闭,则关闭连接,释放对象
If (conn.State <> ConnectionState.Closed) Then
conn.Close()
conn = Nothing
End If
End Sub
End Class
关于七层自己还有好多不理解的地方一定要再接再厉。。。。