机房重构——组合查询

     机房收费系统中有三个功能用到了“组合查询”——可以查询1到3个条件的数据。这三胞胎长得是很像很像滴,上图:

机房重构——组合查询_第1张图片

     学习了设计模式,但是到实际用的时候还是不会啊,看了很多资料博客,在这里实践了一把——用模板方法模式

分析:三个的窗体是一样的,查询的表不一样,字段也就不一样,所以要在抽象出来的父窗体中写一个基本框架,在各自的子窗体中赋值。

1.窗体

父窗体写好以后,子窗体创建:


以“学生信息维护”为例,子窗体与父窗体长的一样,创建好之后控件上有小锁标志,会发现,它是不能动的(事件不可用)

机房重构——组合查询_第2张图片

u层代码如下:这里要写一个虚方法,用来返回字段名,在各个子窗体中就可以重写来给字段赋值了

Public Class FrmPowerQuery

    Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
        CmbActor1.Text = ""
        CmbActor2.Text = ""
        CmbActor3.Text = ""
        CmbFieldName1.Text = ""
        CmbFieldName2.Text = ""
        CmbFieldName3.Text = ""
        CmbRelation1.Text = ""
        CmbRelation2.Text = ""
        TxtMessage1.Text = ""
        TxtMessage2.Text = ""
        TxtMessage3.Text = ""
        DataGridView1.DataSource = ""
    End Sub

    Private Sub BtnOK_Click(sender As Object, e As EventArgs) Handles BtnOK.Click
        If CmbActor1.Text.Trim = "" Or CmbFieldName1.Text.Trim = "" Or TxtMessage1.Text.Trim = "" Then
            MsgBox("请将第一行查询信息补充完整")
            Exit Sub
        End If

        If CmbRelation1.Text <> "" And (CmbActor2.Text.Trim = "" Or CmbFieldName2.Text.Trim = "" Or TxtMessage2.Text.Trim = "") Then
            MsgBox("应该将第二条查询信息补充完整")
            Exit Sub
        End If
        If CmbRelation2.Text <> "" And (CmbActor3.Text.Trim = "" Or CmbFieldName3.Text.Trim = "" Or TxtMessage3.Text.Trim = "") Then
            MsgBox("应将第三条查询信息补充完整")
            Exit Sub
        End If

        '实体赋值
        Dim Queryinfo As New Entity.ePowerQueryEntity
        Queryinfo.DBName = getDTName() '获取数据库名
        Queryinfo.CmbActor1 = SameAsTable(CmbActor1.Text.Trim)  '获得查询的字段名并且转化成sql语句可以识别的语句
        Queryinfo.CmbActor2 = SameAsTable(CmbActor2.Text.Trim)
        Queryinfo.CmbActor3 = SameAsTable(CmbActor3.Text.Trim)
        Queryinfo.CmbFileName1 = SameAsTable(CmbFieldName1.Text.Trim)
        Queryinfo.CmbFileName2 = SameAsTable(CmbFieldName2.Text.Trim)
        Queryinfo.CmbFileName3 = SameAsTable(CmbFieldName3.Text.Trim)
        Queryinfo.CmbRelation1 = SameAsTable(CmbRelation1.Text.Trim)
        Queryinfo.CmbRelation2 = SameAsTable(CmbRelation2.Text.Trim)
        Queryinfo.TxtMessage1 = TxtMessage1.Text.Trim
        Queryinfo.TxtMessage2 = TxtMessage2.Text.Trim
        Queryinfo.TxtMessage3 = TxtMessage3.Text.Trim


        Try
            Dim facade As New Facade.Facade
            Dim table As DataTable
            table = facade.PowerQuery(Queryinfo)

            If table.Rows.Count = 0 Then
                MsgBox("没有查到任何记录")
            Else
                DataGridView1.DataSource = table
            End If

        Catch ex As Exception
            MsgBox("查询过程出错了")
        End Try

    End Sub
    ''' <summary>
    ''' 虚方法 使得表中填写的字段名与数据库中保持一致
    ''' </summary>
    ''' <param name="cmbFileName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function SameAsTable(cmbFileName As String) As String
        Return ""
    End Function
    ''' <summary>
    ''' 
    ''' 虚方法 获得数据库的名字
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function getDTName() As String
        Return ""
    End Function

   
    Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles BtnExit.Click
        Me.Close()
        FrmMain.Show()
    End Sub

    Private Sub FrmPowerQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'combo框只能从下拉菜单里面选择不可以输入
        CmbActor1.DropDownStyle = 2
        CmbActor2.DropDownStyle = 2
        CmbActor3.DropDownStyle = 2
        CmbFieldName1.DropDownStyle = 2
        CmbFieldName2.DropDownStyle = 2
        CmbFieldName3.DropDownStyle = 2
        CmbRelation1.DropDownStyle = 2
        CmbRelation2.DropDownStyle = 2
    End Sub
End Class
学生信息维护 U层代码:

Public Class FrmStudentInfoMaintain1
    Private Sub FrmStudentInfoMaintain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CmbFieldName1.Items.Add("卡号")
        CmbFieldName1.Items.Add("姓名")
        CmbFieldName1.Items.Add("学号")
        CmbFieldName1.Items.Add("性别")
        CmbFieldName1.Items.Add("系别")
        CmbFieldName1.Items.Add("年级")
        CmbFieldName1.Items.Add("班级")

        CmbFieldName2.Items.Add("卡号")
        CmbFieldName2.Items.Add("姓名")
        CmbFieldName2.Items.Add("学号")
        CmbFieldName2.Items.Add("性别")
        CmbFieldName2.Items.Add("系别")
        CmbFieldName2.Items.Add("年级")
        CmbFieldName2.Items.Add("班级")

        CmbFieldName3.Items.Add("卡号")
        CmbFieldName3.Items.Add("姓名")
        CmbFieldName3.Items.Add("学号")
        CmbFieldName3.Items.Add("性别")
        CmbFieldName3.Items.Add("系别")
        CmbFieldName3.Items.Add("年级")
        CmbFieldName3.Items.Add("班级")
    End Sub

    Protected Overrides Function SameAsTable(cmbFileName As String) As String
        Select Case cmbFileName
            Case "卡号"
                SameAsTable = "CardNO"
            Case "姓名"
                SameAsTable = "studentName"
            Case "学号"
                SameAsTable = "studentNO"
            Case "性别"
                SameAsTable = "Sex"
            Case "系别"
                SameAsTable = "Department"
            Case "年级"
                SameAsTable = "Grade"
            Case "班级"
                SameAsTable = "Class"
            Case "与"
                SameAsTable = "and"
            Case "或"
                SameAsTable = "or"
            Case "<>"
                SameAsTable = "<>"
            Case "<"
                SameAsTable = "<"
            Case ">"
                SameAsTable = ">"
            Case "="
                SameAsTable = "="
            Case Else
                SameAsTable = ""
        End Select
    End Function

    Protected Overrides Function getDTName() As String
        Return "Student"
    End Function

End Class
连接数据库:三个功能中用的表不一样,所以在SQLHelper中添加一个方法,不直接传参,代码如下:

 Public Function Query(ByVal cmdText As String, ByVal cmdType As CommandType) As DataTable
        Dim sqlAdapter As SqlDataAdapter '定义数据适配器)
        Dim dt As New DataTable
        Dim ds As New DataSet

        '给cmd赋值
        cmd.CommandText = cmdText   'cmdtext为要执行的sql语句
        cmd.CommandType = cmdType   '命令执行的类型
        cmd.Connection = conn

        sqlAdapter = New SqlDataAdapter(cmd) '实例化Adapter
        Try
            sqlAdapter.Fill(ds) '用adapter将dataset填充
            dt = ds.Tables(0) 'datatable为dataSet的第一个表

        Catch ex As Exception
            MsgBox("数据库操作失败")
        Finally
            Call CloseCmd(cmd) '销毁cmd命令
        End Try
        Return dt
    End Function
D层:

Public Function PowerQuery(ByVal Queryinfo As Entity.ePowerQueryEntity) As DataTable Implements IPowerQuery.PowerQuery
        Dim sqlinfo As String '用于存放sql语句
        Dim table As DataTable
        Dim sqlhelper As New SQLHelper.sqlHelper
        Dim cmdtype As CommandType = New CommandType()


        If Queryinfo.CmbRelation1 = "" Then
            sqlinfo = "Select * from " & Queryinfo.DBName & " where" & Chr(32) & Queryinfo.CmbFileName1 & Queryinfo.CmbActor1 & "'" & Queryinfo.TxtMessage1 & "'"
            '@FileName1 @Actor1 @Message1"
        ElseIf Queryinfo.CmbRelation1 <> "" And Queryinfo.CmbRelation2 = "" Then
            sqlinfo = "select * from" & Chr(32) & Queryinfo.DBName & Chr(32) & "where" & Chr(32) & Queryinfo.CmbFileName1 & Chr(32) & Queryinfo.CmbActor1 & Chr(32) & "'" & Queryinfo.TxtMessage1 & "'" & Chr(32) & Queryinfo.CmbRelation1 & Chr(32) & Queryinfo.CmbFileName2 & Chr(32) & Queryinfo.CmbActor2 & Chr(32) & "'" & Queryinfo.TxtMessage2 & "'"
        Else
            sqlinfo = "select * from" & Chr(32) & Queryinfo.DBName & Chr(32) & "where" & Chr(32) & Queryinfo.CmbFileName1 & Chr(32) & Queryinfo.CmbActor1 & Chr(32) & "'" & Queryinfo.TxtMessage1 & "'" & Chr(32) & Queryinfo.CmbRelation1 & Chr(32) & Queryinfo.CmbFileName2 & Chr(32) & Queryinfo.CmbActor2 & Chr(32) & "'" & Queryinfo.TxtMessage2 & "'" & Chr(32) & Queryinfo.CmbRelation2 & Chr(32) & Queryinfo.CmbFileName3 & Chr(32) & Queryinfo.CmbActor3 & Chr(32) & "'" & Queryinfo.TxtMessage3 & "'"
        End If
        table = sqlhelper.Query(sqlinfo, CommandType.Text)
        Return table
    End Function

做完组合查询三个功能以后,感觉设计模式确实很神奇,简洁方便。自己写的代码还是有很多重复的地方,有很多漏洞,看别人的博客学到很多方法,开始觉得很难,做完了也就不觉得了,不要被自己吓倒,慢慢积累。





你可能感兴趣的:(机房重构——组合查询)