• vb.net版机房收费——助你学会七层架构(二)反射+抽象工厂


       上一篇咱们做好了准备工作。数据库设计和Entity层,如今介绍

      4、反射+抽象工厂

      反射:用来消除Switch和if的,这里我尽量简单地介绍,以便大家理解。反射其有用起来非常easy。你就觉得他就是决定:去某个地方找应该要实例化的类是哪个。怎么理解?


     

    '**************************
    '文 件 名:DataAccess
    '命名空间:Factory
    '内    容:
    '功    能:
    '文件关系:
    '作    者:邱慕夏
    '小    组:邱慕夏
    '生成日期:2014-06-09 9:17:51
    '版 本 号:V1.0.0.0
    '改动日志:
    '版权说明:
    '***************************
    Imports System.Reflection
    Imports IDAL
    Public Class DataAccess
        Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBUser")    '这里改动配置文件就能够确定是查询那个表了。
    
        Dim StrQueryWorkLog As String = System.Configuration.ConfigurationSettings.AppSettings("DBStrQueryWorkLog")
    
        '/// <summary>
        '/// depiction:<实例化一个DAL中的User表的类>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回值是一个boolean值>
        '/// </returns>
        Public Function CreateUserInfo() As IDAL.IUser
            Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & strDB), IUser)
        End Function
        '/// <summary>
        '/// depiction:<实例化一个DAL中的WorkLog表的类>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回值是要实例化的表>
        '/// </returns>
        Public Function CreateWorkLog() As IDAL.IWorkLog
            Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & StrQueryWorkLog), IWorkLog)
        End Function
    End Class

       我给大家写完整就是这种。DAL是D层命名空间,DAL.表名,是这个意思。StrQueryWroklog事实上这个值说白了就是一个变量,放在配置文件中了,你就觉得好像非常高大上一样,事实上不然。个人觉得这里全然能够改为:

        Dim strQueryWorkLog As String = "WorklogDAL"
        Dim strDB As String = "LoginDAL"

      就是两个变量而已,不用害怕,想用配置文件。之后,我会给大家细说,如今因为篇幅问题,就不写配置文件了,大家把上面的两行代码:

        Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBUser")

        Dim StrQueryWorkLog As String = System.Configuration.ConfigurationSettings.AppSettings("DBStrQueryWorkLog")

      改成我上面写得    

      Dim strQueryWorkLog As String = "WorklogDAL"

      Dim strDB As String = "LoginDAL"

      全然没有影响,嘿嘿。

       

      5、D层的构建

      D层理解起来非常easy就是针对数据库的增删改查即可了,但我们用的是面向对象的语言,所以我们就要考虑代码的复用问题,反复的代码我们给它分类。记住:分类是为了抽象;我们给它抽象出来一个SQLHelper分为四类:查询返回boolean、查询返回实体、增删改返回boolean、增删改返回实体。

      抽象出来的sqlhelper我就仅仅写一下Login功能须要的。User表查询分会boolean、worklog增删改返回boolean。(由于它们都不须要返回实体)。

      

       

    '**************************
    '文 件 名:SqlHelper
    '命名空间:DAL
    '内    容:
    '功    能:
    '文件关系:
    '作    者:邱慕夏
    '小    组:邱慕夏
    '生成日期:2014-06-07 14:47:28
    '版 本 号:V1.0.0.0
    '改动日志:
    '版权说明:
    '***************************
    Imports System.Data.SqlClient
    Imports System.Configuration
    
    Public Class SqlHelper
        Dim strConnection As String = System.Configuration.ConfigurationManager.AppSettings("strConnection")
        '定义连接
        Dim conn As SqlConnection
        '定义命令
        Dim cmd As SqlCommand
        '初始化连接对象
        Public Sub New()
            conn = New SqlConnection(strConnection)
        End Sub
        '------------------------------------------
        '运行增删改三个,不须要返回实体类型。返回Boolean类型。True为返回成功,反之,返回失败
        '应用存储过程
        '------------------------------------------
        '/// <summary>
        '/// depiction:<增删改功能,但不传回參数>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回值是boolean类型的,就是说成功了传回的就是True。没有改动成功的为False>
        ' /// </returns>
    
        Public Function ExecuteNonQuery(ByVal strText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As Boolean
            Dim cmd As New SqlCommand
            cmd.CommandText = strText '命令文本
            cmd.CommandType = cmdType '命令类型
            cmd.Connection = conn '连接数据库
    
            cmd.Parameters.AddRange(sqlParams) '传參
    
            Dim flag As Boolean = False  '定义返回值
    
            Try
                conn.Open()
                flag = cmd.ExecuteNonQuery()
                cmd.Parameters.Clear()
                Return flag
            Catch ex As Exception
                flag = False
            Finally
                Call CloseConnection(conn)
                Call CloseCmd(cmd)
            End Try
            Return flag
        End Function
     
    
        '/// <summary>
        '/// depiction:<查询功能,不传回參数>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回值是boolean类型的,就是说成功了传回的就是True,没有改动成功的为False>
        ' /// </returns>
        Public Function ExecuteQuery(ByVal strText As String, ByVal cmdType As CommandType, ByVal sqlParams As SqlParameter()) As Boolean
            Dim cmd As New SqlCommand
            cmd.CommandText = strText '命令文本
            cmd.CommandType = cmdType '命令类型是存储过程
            cmd.Connection = conn '连接数据库
            Dim reader As SqlClient.SqlDataReader                                               '读取数据库中的表
    
            cmd.Parameters.AddRange(sqlParams) '传參
    
            Dim flag As Boolean = False  '定义返回值
    
            Try
                conn.Open()
                reader = cmd.ExecuteReader()
    
                flag = reader.Read()
            Catch ex As Exception
                flag = False
                MsgBox("查询失败", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "警告")
            Finally
                Call CloseConnection(conn)
                Call CloseCmd(cmd)
            End Try
            Return flag
        End Function
    
        '/// <summary>
        '/// depiction:<关闭命令>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回为>
        ' /// </returns>
        Public Sub CloseCmd(ByVal cmd As SqlCommand)
            If Not IsNothing(cmd) Then '推断是否为空
                cmd.Dispose() '销毁
                cmd = Nothing
            End If
        End Sub
    
        '/// <summary>
        '/// depiction:<关闭连接>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回为>
        ' /// </returns>
        Public Sub CloseConnection(ByVal conn As SqlConnection)
            If Not IsNothing(conn.State <> ConnectionState.Closed) Then
                conn.Close() '关闭连接
                conn = Nothing
            End If
        End Sub
     End Class
    

       不难看出,我仅仅在这里用了两个。多了大家不easy接受,好的,这里说一下:好的凝视能让你一眼看到这个function的功能。所以我们一定要写好凝视。

      SQLHelper我把它放在D层。相同放在D层的是针对各个表进行操作的函数。我的D层是依照表来划分的。给大家看一下,有个宏观把握:


     须要注意的是SqlHelper放在D层,我们须要的表LoginDAL表和WorkLogDAL表,另一个QueryStudentDAL不是表,是一个视图。我也放在这里了。

      大家一定要先建SqlHelper,在建LoginDAL和WorkLogDAL,两个表代码:


    '**************************
    '文 件 名:Login
    '命名空间:DAL
    '内    容:
    '功    能:
    '文件关系:
    '作    者:邱慕夏
    '小    组:邱慕夏
    '生成日期:2014-06-07 17:25:05
    '版 本 号:V1.0.0.0
    '改动日志:
    '版权说明:
    '***************************
    Imports IDAL
    Imports System.Data.SqlClient
    Public Class LoginDAL : Implements IDAL.IUser
    
    
        '/// <summary>
        '/// depiction:<登陆功能,调用sqlhelper,放在DAL层>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<对方法返回值的说明,该说明必须明白说明返回的值代表什么含义>
        ' /// </returns>
        '/// <summary>
        '/// depiction:<改动password之前。先要验证一下password是否正确>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回boolean就可以>
        ' /// </returns>
    
        Public Function User_Login(user As Entity.LoginEntity) As DataTable Implements IUser.User_Login
            Dim sqlparams As SqlParameter() = {New SqlParameter("@UserID", user.UserID), New SqlParameter("@Password", user.Password)}
            Dim cmdText As String = "sp_SelectUser"
            Dim helper As New SqlHelper '实例化SqlHelper
            Dim cmdType As CommandType = New CommandType()
            cmdType = CommandType.StoredProcedure '定义命令类型为存储过程
            Dim table As New DataTable
            table = helper.ExecuteQueryVar(cmdText, cmdType, sqlparams) '定义返回值
            Return table
        End Function
    end Class


      WorkLogDAL的代码:

    '**************************
    '文 件 名:WorkLogDAL
    '命名空间:DAL
    '内    容:
    '功    能:
    '文件关系:
    '作    者:邱慕夏
    '小    组:邱慕夏
    '生成日期:2014/6/15 11:17:48
    '版 本 号:V1.0.0.0
    '改动日志:
    '版权说明:
    '***************************
    Imports IDAL
    Imports System.Data.SqlClient
        '/// <summary>
        '/// depiction:<实例化一个IDAL中的worklog类,登陆的时候。顺便记录进去>
        '/// </summary>
        '/// <param name="<參数名称>"><參数说明></param>
        '/// <returns>
        '///<返回值是一个boolean值>
        '/// </returns>
        Public Function SaveWorkLog(worklog As Entity.WorkLogEntity) As Boolean Implements IWorkLog.SaveWorkLog
            Dim strText As String = "INSERT INTO T_WorkLog(UserID,Level,LoginDateTime,Computer,Status) VALUES(@UserID,@Level,@LoginDateTime,@Computer,@Status)"
            Dim sqlparams As SqlParameter() = {New SqlParameter("@UserID", worklog.UserID), New SqlParameter("@Level", Entity.LoginEntity.UserLevel), New SqlParameter("@LoginDateTime", worklog.LoginDateTime), New SqlParameter("@Computer", worklog.Computer), New SqlParameter("@Status", worklog.Status)}
            Dim cmdType As CommandType = CommandType.Text
            Dim helper As New SqlHelper
            Return helper.ExecuteNonQuery(strText, cmdType, sqlparams)
        End Function
    
    End Class


       事实上大家能够细致看就能够看到,我的这两种里面写的东西。不是一样的,看代码中的:

           Dim cmdText As String = "sp_SelectUser"

      这个是存储过程的名字,那我们怎么知道它是存储过程的,看这一行:

           Dim cmdType As CommandType = New CommandType()
           cmdType = CommandType.StoredProcedure '定义命令类型为存储过程

      这两行,就告诉我们是存储过程。它们是相应的,那么我不想用存储过程,我想用sql语句怎么办:

           Dim strText As String = "INSERT INTO T_WorkLog(UserID,Level,LoginDateTime,Computer,Status) VALUES(@UserID,@Level,@LoginDateTime,@Computer,@Status)"

      这是Worklog中的一段,后面我们非常熟悉,就是添加一条数据。跟存储过程不用。它和:

            Dim cmdType As CommandType = CommandType.Text

      是相应的,大家一定不要搞混了。

      好了里面的我们都弄清了。那我们怎么告诉SqlHelper我们的參数、sql语句、存储过程等。

    大家看:

            Return helper.ExecuteNonQuery(strText, cmdType, sqlparams)

      这句话,就是调用sqlhelper,helper是实例了一个sqlhelper的名字。return返回helper返回的东西(boolean),事实上这里helper的这个函数就是返回boolean,所以我懒省事就这样写了,一样的,分开写就是这种:

      dim flag as boolean=helper.ExecuteNonQuery(strText, cmdType, sqlparams)

      return flag

      一样的。

    非常清楚了是吧?

      6、接口层的建立

      接口层非常easy。就是工厂生产接口,D层实现接口。继承接口,让B层就能够直接调用工厂,工厂生产接口。让工厂决定实例化那个接口。这样看起来。好像是B层调用的是D层,而实际上是调用工厂,调用IDAL层。

    解除B层和D层的耦合。


      

             这里我感觉非常抱歉的是,上面用的是LoginDAL。接口层用的是IUser,这是不正确的,一定要保持一致。

     

    Imports Entity
    Public Interface IUser
        Function User_Login(ByVal user As Entity.LoginEntity) As System.Data.DataTable
    End Interface
    

       IWorklog :

    Public Interface IWorkLog
        Function SaveWorkLog(ByVal worklog As Entity.WorkLogEntity) As Boolean
    End Interface
    

      以下我就要解说B层是怎样通过接口层调用D层的了。





     


  • 相关阅读:
    转载 NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel
    Microsoft Visual SourceSafe 6.0 无法关联项目
    dynamic json
    c#查找string数组的某一个值的索引
    C#中 删除掉字符串数组中的空字符串
    c# 比较两个数组每一个值是否相等
    c#比较两个数组的差异
    C#动态操作DataTable(新增行、列、查询行、列等)
    C#数字转字母,ASCII码转换
    c#中使程序跳到指定行中
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6748584.html
Copyright © 2020-2023  润新知