• 七层登录——VB.NET版


        敲完三层后,感觉还是对三层架构没有那么亲切,和小伙伴交流后,他们说多多敲几遍,就懂了,其实就是那么几条线,所以:不管会不会,先去做吧!

    下面是关于七层的包图:


    我的解决方案:


    代码部分:

    U层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity.UserEntity
    Imports Facade
    Imports System.Net.Dns
    
    Public Class FrmLogin
        Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
            Dim strResult1 As Boolean
            Dim strResult2 As Boolean
            Dim FacadeLogin As New Facade.LoginFacade '定义一个外观对象
            Dim UserInfo As New Login.Entity.UserEntity '定义一个实体类对象
    
            '判断文本框
            If txtUsername.Text = "" Then
                MessageBox.Show("温馨提示,思密达输入用户名", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                txtUsername.Text = "" '设置为空
                txtUsername.Focus() '用户名获得焦点
                Exit Sub
            End If
    
            If txtPassword.Text = "" Then
                MessageBox.Show("思密达,请输入密码", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                txtPassword.Text = "" '设置为空
                txtPassword.Focus() '密码框获得焦点
                Exit Sub
            End If
    
            Try
    
                '将文本框中的参数传递给实体
                UserInfo.UserName = txtUsername.Text.Trim() '将用户名和密码赋值给实体类的对象UserinfoUserName;Password属性;
                UserInfo.Password = txtPassword.Text.Trim() '从而Userinfo获取了U层的参数,通过外观层,传递到B层进行判断;
                strResult1 = FacadeLogin.CheckUser(UserInfo) '将U层的用户名通过外观层传到B层,得到外观的返回值;
                strResult2 = FacadeLogin.CheckPwd(UserInfo)
    
                If strResult1 = False Or strResult2 = False Then '通过返回值来判断用户是否存在;
                    MsgBox("用户名或密码不正确!")
                    txtUsername.Text = ""
                    txtPassword.Text = ""
                    txtUsername.Focus()
                Else
                    MsgBox("登录成功!Amazing")
                End If
    
            Catch ex As Exception
                MsgBox("用户不存在或者密码不正确!")
                txtUsername.Text = ""
                txtPassword.Text = ""
                txtUsername.Focus()
            End Try
        End Sub
    
        Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
            Me.Close() '关闭窗体
        End Sub
    
    
        Private Sub FrmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            '获取计算机名称
            Dim Address() As System.Net.IPAddress 'class system.net.IPAddress提供网际协议(IP)地址;
            'class system.net.dns提供简单的域名解析功能;
            'GetHostName()获取本地主机名;
            'AddressList获取或设置与主机关联的IP列表;
            Address = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList
            txtComputer.Text = System.Net.Dns.GetHostName().ToString()
        End Sub
    End Class</span>

    Façade层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity
    Imports Login.BLL
    Imports System.Reflection
    
    Public Class LoginFacade
    
        Public Function CheckUser(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
            Dim isUserExists As New Login.BLL.UserBLL() '实例化B层UserBLL类对象;
            Dim flag As Boolean
            flag = isUserExists.IsUserExists(UserInfo) '判断是否存在该用户
            Return flag
        End Function
    
        Public Function CheckPwd(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
            Dim isPwd As New Login.BLL.UserBLL() '实例化UserBLL对象;
            Dim flag1 As Boolean
            flag1 = isPwd.IsPwdRight(UserInfo) '判断userinfo对象的密码是否存在;
            Return flag1
        End Function
    End Class</span>

    B层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class UserBLL
        '检查用户是否存在
        Public Function IsUserExists(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
            Dim Iuser As IDAL.IuserInfoDAL
            '调用创建用户的工厂方法
            Iuser = Factory.LoginFactory.CreateUserInfo
            Dim table As DataTable
            Dim flag As Boolean
            table = Iuser.selectUser(UserInfo)
    
            '由于在sqlhelper中以表格的形式存在(adataset.Tables(0)),且开头第一列表示为0,所以Item(0)表示为用户名;
            If table.Rows(0).Item(0) = 0 Then '第一行第一列
                flag = False
            Else
                flag = True
            End If
            Return flag
        End Function
    
        '查看密码是否正确
        Public Function IsPwdRight(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
            Dim Iuser As IDAL.IuserInfoDAL
            Dim table As DataTable '中间变量用来存储数据
            Dim flag1 As Boolean
            Iuser = Factory.LoginFactory.CreateUserInfo '调用工厂方法的Createuserinfo来创建iuser;
            table = Iuser.selectUser(UserInfo) '调用接口的方法selectUser
            If table.Rows(0).Item(0) = 0 Then
                flag1 = False
            Else
                flag1 = True
            End If
            Return flag1
        End Function
    End Class</span>

    Factory层:

    为什么要用反射?

    个人认为,接口本身没有没有具体实现,反射就是把接口的dll加载进内存,然后通过反射,实例化D层的类,调用dll方法。将B层的参数通过反射的方法, 在D层做具体实现。(仅供参考)

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Configuration
    Imports System.Reflection '使用反射来帮我们克服抽象工厂模式的先天不足
    Imports Login.IDAL
    Imports Login.DAL
    
    Public Class LoginFactory
        '读配置文件,D层的每个类在配置文件里面对应一个key
        '下面这句式把key变成变量,然后在下面这个方法中用这个变量就可以应用D层里面这个类了;
        Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBString")
        ''' <summary>
        ''' ’实例化LoginDAL中users表中一个类
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function CreateUserInfo() As Login.IDAL.IuserInfoDAL
            'CType是一个内联函数,将前面的部分转换为后半部分;
            'LoginDAL为程序集名称;
            'Login.DAL为命名空间名称;
            'IuserInfoDAL 为要实例化的“类名”;
            'CreateUserInfo ’创建实例;
            Return CType(Assembly.Load("LoginDAL").CreateInstance("Login.DAL" & "." & "UserDAL"), IuserInfoDAL)
        End Function
    End Class</span>

    接口层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity
    Public Interface IuserInfoDAL
        'UserInfo为用户的实体,是由实体类实例化而来的
        '即所谓的传实体
        '此接口定义了一个方法,用来检测用户是否存在
        Function selectUser(ByVal UserInfo As Login.Entity.UserEntity) As DataTable
    End Interface</span>

    D层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Data.SqlClient
    'system.data.sqlClient命名空间是SQL SERVER的.netframework数据提供的程序
    'sql server的.net framework数据提供程序描述了一个类集合,这个类用于访问托管中的sql server数据库;
    Imports Login.Entity
    Imports Login.IDAL
    Imports SQLHelper
    
    Public Class UserDAL : Implements IDAL.IuserInfoDAL '实现接口中的方法;
        '声明并实例化sqlhelper类
        Private SqlHelper As SQLHelper.sqlhelper = New SQLHelper.sqlhelper
        Public Function selectUser(UserInfo As Login.Entity.UserEntity) As DataTable Implements IuserInfoDAL.selectUser
            Dim Sql As String
            Dim table As DataTable '中间变量用于存储从数据库中查找信息
            Dim sqlConnectStr As String = "server =ZLT;database=Login;uid=sa;pwd=123"
            '声明并实例化参数数组
            Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserName), New SqlParameter("@Password", UserInfo.Password)}
            Sql = "select * from Users where UserName=@UserName and Password=@Password" 'SQL是查询到的信息;
            '下句为调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值;
            table = SqlHelper.GetDataTable(Sql, CommandType.Text, sqlParams)
            Return table
        End Function
    End Class</span>

    Entity层:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class UserEntity
    
        '区别变量的名字,变量的名字比数据库多“_”
        Private _UserName As String
        Private _Password As String
        Private _UserID As String
        Private _level As String
        Private _Holder As String
    
        '以下为可读写属性,名字和数据库中的一样
        Public Property UserName() As String
            Get
                Return _UserName
            End Get
            Set(value As String)
                _UserName = value
            End Set
        End Property
    
        Public Property Password() As String
            Get
                Return _Password
            End Get
            Set(value As String)
                _Password = value
            End Set
        End Property
    End Class</span>

    SQLHelper层:

    为什么要用SQLHelper?

    Sqlhelper封装了对数据库的增删改查,所以减少了代码的量,提高了系统性能;具体见:点我

    <span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Data.SqlClient
    Imports System.Configuration
    Imports System.Data
    Imports System.Reflection
    
    Public Class sqlhelper
        'configurationManager表示读配置文件;
        'appsetting获取配置文件的数据;
        Public Shared ConnectionString As String = ConfigurationManager.AppSettings("sqlConnectStr")
        'sqlDataAdapter表示用于填充Data.Dataset和更新SQL SERVER数据库的一组数组命令和一个数据库连接;
        Private Shared Property adaptor As SqlDataAdapter
        '''<summary>
        '''执行带参数的查询操作
        '''</summary>
        ''' <param name="cmdTxt">参数cmdTxt为所要执行的sql语句</param>
        ''' <param name="cmdType">查询时的查询方式</param>
        ''' <param name="paras">查询时的命令参数paras</param>
        ''' <returns>查询后以表示的方式返回,如下面adataset.Tables(0)</returns>
        ''' <remarks></remarks>
        Public Shared Function GetDataTable(ByVal cmdTxt As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable
            Dim conn As SqlConnection = New SqlConnection(ConnectionString) '建立数据库连接;
            Dim cmd As SqlCommand '定义命令变量;
            Dim adaptor As SqlDataAdapter '定义数据库适配器;
            Dim adataset As DataSet '定义并实例化数据库缓冲区对象,即从数据库传入对象;
            cmd = New SqlCommand(cmdTxt, conn) '在Conn上实例化命令变量,并执行cmdType;
            cmd.CommandType = cmdType '执行命令的类型
            cmd.Parameters.AddRange(paras) '命令执行时的参数
            adaptor = New SqlDataAdapter(cmd) '将结果绑定到数据库适配器变量adaptor上面;
            adataset = New DataSet 'dataset表示数据内存中缓存;
            Try
                '如果数据库连接状态为关闭则将其打开;
                If conn.State = ConnectionState.Closed Then
                    conn.Open()
                End If
                adaptor.Fill(adataset) '向adaptor对象中填充要查询的数据;
            Catch ex As Exception
                '错误处理程序,出错则提示
                MsgBox(ex.Message, , "数据库操作!")
            Finally
                '如果连接状态为打开,则将其关闭,释放内存;
                If conn.State = ConnectionState.Open Then
                    conn.Close()
                End If
            End Try
            '以表格的形式返回结果
            Return adataset.Tables(0)
        End Function
        Function GetDataTable() As DataTable
            Throw New NotImplementedException
        End Function
    End Class</span>

    生成依赖项关系图:


    小结:

        这个阶段总是在参考别人的博客学习,学到了很多东西,自己也亲自调试了好多错误(具体错误:点我),成长了好多,在以后机房重构的过程中,希望自己多多实践自己的想法。

    1、  站在巨人的肩膀上学习,让我们知道了许多以前不知道的地方;

    2、  代码如人生,重要的不是代码,而是思想。


    感谢您的宝贵时间~~~

  • 相关阅读:
    解决Tomcat请求中文乱码的问题
    Bootstrap 兼容 IE
    Spring+MyBatis多数据源配置实现
    年度总结与计划
    AJAX 提交表单以及文件上传
    移动端Web开发调试工具:Chrome DevTools
    SpringMVC 之 @ResponseBody 和 @RequestBody
    goland快键键防忘
    MySQL日志文件影响数据库的各种类型活动
    何为云计算
  • 原文地址:https://www.cnblogs.com/zhoulitong/p/6412430.html
Copyright © 2020-2023  润新知