上一篇咱们做好了准备工作。数据库设计和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层的了。

vb.net版机房收费——助你学会七层架构(二)反射+抽象工厂的更多相关文章

  1. vb.net版机房收费——助你学会七层架构(一)

    我自己写机房的时候,看非常多高人的博客,各种的借鉴,当初务必的纠结,如今整个机房敲完了,写这篇博客给大家一个总体上的.简单理解的七层,期望大家看完这篇文章之后,不会这个纠结了. 首先大家得看了我的上一 ...

  2. vb.net版机房收费系统——教你七层架构(三)—外观模式

    上次我们看到了D层是如何运作的,如今.我简单演示一下我的外观和B层是如何和U层和D层打交道的. 首先我跟大家说的是我的外观是依照界面功能划分的,粒度有点小,大家在做的时候,记得外观有几个即可了,可是不 ...

  3. VB.NET版机房收费系统---导出Excel表格

    datagridview,翻译成中文的意思是数据表格显示,使用DataGridView控件,能够显示和编辑来自不同类型的数据源的表格,将数据绑定到DataGridView控件很easy和直观,大多数情 ...

  4. VB.NET版机房收费系统---异常处理

    异常处理,英文名为Exceptional Handling, 那时年少,还记得那年一起学习过的VB6.0的时候,常常使用ONError的错误语句.与传统VB6.0中的OnError语句相比.NET平台 ...

  5. VB.net版机房收费系统——结账功能实现(调错与优化)

    调错部分 上一篇博客<VB.net版机房收费系统--结账功能实现(代码部分>说的是结账功能的实现,亮出了代码.是在为这篇博客做铺垫.尽管结账功能代码是借鉴的巨人的博客.可是自己比着葫芦画瓢 ...

  6. VB.NET版机房收费系统---七仙女之系统登录

    VB.NET第一版机房收费系统,告一段落,验收的时候.问题也是大大的存在,没实用上设计模式,什么触发器.存储过程,都没实用上.看看其她小伙伴的,七层实现登录?那是什么东东,相比較我的三层而言,多了两倍 ...

  7. VB.NET版机房收费系统---报表

    报表,即报告情况的表格,简单的说:报表就是用表格.图表等格式来动态显示数据,可以用公式表示为:"报表 = 多样的格式 + 动态的数据". 在没有计算机以前,人们利用纸和笔来记录数据 ...

  8. VB.NET版机房收费系统—数据库设计

    之前第一遍机房收费的时候,用的数据库是别人的.认知也仅仅能建立在别人的基础上,等自考中<数据库系统原理>这本书学完了之后,再去看曾经的数据库,发现数据库真的还须要进一步的优化.以下是我设计 ...

  9. VB.NET版机房收费系统---外观层如何写

    外观设计模式,<大话设计模式>第103页详细讲解,不记得这块知识的小伙伴可以翻阅翻阅,看过设计模式,敲过书上的例子,只是学习的第一步,接着,如果在我们的项目中灵活应用,把设计模式用出花儿来 ...

随机推荐

  1. CF 1003D Coins and Queries【位运算/硬币值都为2的幂/贪心】

    Polycarp has n coins, the value of the i-th coin is ai. It is guaranteed that all the values are int ...

  2. dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

    1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total ...

  3. (转)python之并行任务的技巧

    Python的并发处理能力臭名昭著.先撇开线程以及GIL方面的问题不说,我觉得多线程问题的根源不在技术上而在于理念.大部分关于Pyhon线程和多进程的资料虽然都很不错,但却过于细节.这些资料讲的都是虎 ...

  4. [BZOJ1143][CTSC2008]祭祀river(Dilworth定理+二分图匹配)

    题意:给你一张n个点的DAG,最大化选择的点数,是点之间两两不可达. 要从Dilworth定理说起. Dilworth定理是定义在偏序集上的,也可以从图论的角度解释.偏序集中两个元素能比较大小,则在图 ...

  5. 8.1(java学习笔记)注解(Annotation)

    一.Annotation Annotation不是程序本身,但它可以对程序进行解释,这一点和注释类似. 但最大的不同点在于,注解可以被其他程序读取,然后可以对其进行一些有针对性操作. 这是注解与注释最 ...

  6. 对三个数排序 Exercise06_05

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:对三个数排序 * */ public class Exercise06_0 ...

  7. JS面向对象函数的四种调用模式

    函数的四种调用模式 概念 在 js 中,无论是函数, 还是方法, 还是事件, 还是构造器,...这些东西的本质都是函数 函数, 方法, 事件, 构造器,...只是所处的位置不同 这四种模式分别是 函数 ...

  8. 三星s3c24xx平台GPIO操作详解

    转:http://blog.chinaunix.net/uid-22030783-id-3391515.html 先介绍三星S3C24XX平台BSP中定义外设寄存器和GPIO的相关头文件 以linux ...

  9. AtomicInteger类的简单应用

    AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字.而AtomicIn ...

  10. String的解析

    String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...