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

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

4、反射+抽象工厂

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


'**************************
'文 件 名: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层理解起来很简单就是针对数据库的增删改查就行了,但我们用的是面向对象的语言,所以我们就要考虑代码的复用问题,重复的代码我们给它分类。记住:分类是为了抽象;我们给它抽象出来一个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 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

不难看出,我只在这里用了两个,多了大家不容易接受,好的,这里说一下:好的注释能让你一眼看到这个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:<修改密码之前,先要验证一下密码是否正确>
    '/// </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,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,@Status)"

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

Dim cmdType As CommandType = CommandType.Text

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

好了里面的我们都弄清了,那我们怎么告诉sqlHelper我们的参数、sql语句、存储过程等。大家看:

Return helper.ExecuteNonQuery(strText,sqlparams)

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

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

return flag

一样的。很清楚了是吧?

6、接口层的建立

接口层很简单,就是工厂生产接口,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层的了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 -------------------------------- 数字类型的格式化 --------------------------------     固定格式参数:     General Number 普通数字,如可以用来去掉千位分隔号     format$("100,1
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和系统设置的区域语言的日期和时间格式相关。意思是尽管你用诸如 Format(Now, "MM/dd/yyyy"),如果系统的设置格式区域语言的日期和时间格式分隔符是"-",那他还会显示为 MM-dd-yyyy     只有拼凑: <%response.write
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接添加本ApplicationEvents.vb 到工程即可 ‘添加后还需要一个From用来显示错误。如果到这步还不会则需要先打好基础啦 ‘======================================================== ‘以下事件
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶K3 BOS的插件官方是用VB6编写的,如果  能用.Net下的语言工具开发BOS插件是一件很愉快的事情,其中缘由不言而喻,而本文则是个人首创,实现在了用V
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, tmpStr As String, s As String Dim x As Integer, y As Integer, subStr As String If MsgBox("确定要分列处理吗?请确定分列的数据会覆盖它后面的单元格!", _
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) 2 Dim path As String, hash As String 3 For Each fil
  Imports MySql.Data.MySqlClient Public Class Form1 ‘ GLOBAL DECLARATIONS Dim conString As String = "Server=localhost;Database=net2;Uid=root;Pwd=123456;" Dim con As New MySqlConnection
‘導入命名空間 Imports ADODB Imports Microsoft.Office.Interop   Private Sub A1() Dim Sql As String Dim Cnn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim S As String   S = "Provider=OraOLEDB.Oracl
Imports System.IO Imports System.Threading Imports System.Diagnostics Public Class Form1 Dim A(254) As String    Function ping(ByVal IP As Integer) As String Dim IPAddress As String IPAddress = "10.0.
VB运行EXE程序,并等待其运行结束 参考:https://blog.csdn.net/useway/article/details/5494084 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Pr
今天碰到一个问题,登陆的时候,如果不需要验证手机号为空,则不去验证手机号 因为登陆的时候所有的验证信息都存放在一个数组里 Dim CheckUserInfo() As String ={UserBirthday, SecEmail, UserMob, UserSex, RealNameFirst, RealName, CheckCardID, CheckCardType, Contactemail
在VB6.0中,数据访问接口有三种: 1、ActiveX数据对象(ADO) 2、远程数据对象(RDO) 3、数据访问对象(DAO) 1.使用ADO(ActiveX Data Objec,ActiveX数据对象)连接SQL Server 1)使用ADO控件连接 使用ADO控件的ConnectionString属性就可以连接SQL Server,该属性包含一个由分号分隔的argument=value语
注:大家如果没有VB6.0的安装文件,可自行百度一下下载,一般文件大小在200M左右的均为完整版的软件,可以使用。   特别提示:安装此软件的时候最好退出360杀毒软件(包括360安全卫士,电脑管家等,如果电脑上有这些软件的话),因为现如今的360杀毒软件直接会对VB6.0软件误报,这样的话就可能会在安装过程中被误报阻止而导致安装失败,或者是安装后缺乏很多必须的组件(其它的杀毒软件或安全卫士之类的
Private Sub Form_Load() Call conndb End Sub Private Function conndb() Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Dim strCn, sql As String Dim db_host As String Dim db_user As String
  PPSM06S70:  Add  moddate  EDITSPRINTJOB:  MAX(TO_CHAR(ETRN.MODDATE, ‘yyyy/mm/dd/HH24:MI AM‘)) ACTUAL_SHIPDATE   4.Test Scenario (1) :Query SQL Test DN:8016578337 SELECT CTRN.TKCTID TRUCK_ID,        
  沒有出現CrystalReportViewer時,須安裝CRforVS_13_0. 新增1個數據集,新增1個數據表,添加二列,列名要和資料庫名一樣. 修改目標Framework 修改app.config, <startup >改成<startup useLegacyV2RuntimeActivationPolicy ="true">  CrystalReport1.rpt增加數據庫專家 在表單
Imports System.Threading Imports System Public Class Form1 Dim th1, th2 As Thread Public Sub Method1() Dim i As Integer For i = 1 To 100 If Me.Label1.BackColor =
Friend Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711 Friend Const PROCESS_VM_READ = &H10 Friend Const PROCESS_VM_WRITE = &H20 Friend Const PAGE_READONLY = &H2 Friend Const PAGE_READWRITE = &H4 Friend
以下代码随手写的 并没有大量测试 效率也有待提升 如果需要C#的请自行转换 Function SplitBytes(Data As Byte(), Delimiter As Byte()) As List(Of Byte()) Dim i = 0 Dim List As New List(Of Byte()) Dim bytes As New
Imports System.Data.SqlClient Public Class Form1 REM Public conn1 As SqlConnection = New SqlConnection("server=.; Integrated Security=False;Initial Catalog= mydatabase1; User ID= sa;password")