组合查询——继承与多态的小练习

简介:                  上次个人版机房收费做的时候,组合查询这里做的不好,没有抽出模板,导致感觉有很多冗余,这次自己挑U层,一方面是感觉自己的B层和D层做的可以提升的空间目前很小了,另一方面就是想加强一下自己对细节的注意问题。

      

          上次个人版机房收费做的时候,组合查询这里做的不好,没有抽出模板,导致感觉有很多冗余,这次自己挑U层,一方面是感觉自己的B层和D层做的可以提升的空间目前很小了,另一方面就是想加强一下自己对细节的注意问题。



            上次组合查询是这样的,以代码为例:



           



       U层代码如下:

    


Imports System.Collections '引入HashTable类


Public Class frmColWorkInfo
    Dim HtZD As New Hashtable   '定义处理字段名转换的hashtable
    Dim HtZh As New Hashtable '定义处理组合关系转换的hashtable

#Region "单例模式:用来判断本窗体是否已经实例化"

    Private Shared ColWorkInfo As frmColWorkInfo = Nothing  '定义一个静态的类变量

    Private Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
    End Sub

    Public Shared Sub GetInstance() ' As frmCheckBalance '用来出现实例

        If IsNothing(ColWorkInfo) OrElse ColWorkInfo.IsDisposed Then '如果没有实例化
            '注意:1,要判断窗体是否已被实例化和窗体是否被销毁过(当关闭一个窗体时,资源被释放,但是并不是nothing)
            '     2,orelse产生了逻辑短路的问题,如果这里用Or会产生错误,因为可能会引用不存在的对象。

            ColWorkInfo = New frmColWorkInfo '实例化checkbanlance
        End If

        'ColWorkInfo.MdiParent = frmMain '设置父窗体
        ColWorkInfo.Show()     '显示窗体出来,但是此时子窗体还是被隐藏在下层的,必须要通过SetParent将它拿到上层来
        SetParent(ColWorkInfo.Handle.ToInt64, frmMain.Handle.ToInt64)  '设置窗体置前

        'Return checkBalance '返回
    End Sub

#End Region

    Private Sub frmColWorkInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        '''''''''''''''''''''' HtZD '''''''''''''''''''''''处理字段名的转换'''''''''''''''''''''
        Dim ZDname() As String
        Dim eZdValue() As String
        MyDataGrid.AutoGenerateColumns = False

        '字段对应英文
        ZDname = {"教师", "级别", "注册日期", "注册时间", "注销日期", "注销时间", "机器名"}
        eZdValue = {"UserName", "tealevel", "regdate", "regtime", "DelDate", "DelTime", "reger"}

        '加载中文字段到下拉列表框中
        CmbZD1.Items.AddRange(ZDname)
        CmbZD2.Items.AddRange(ZDname)
        CmbZD3.Items.AddRange(ZDname)

        '中文为key,英文为value添加到hashtable
        For i As Integer = 0 To ZDname.Count - 1
            HtZD.Add(ZDname(i), eZdValue(i))
        Next
        '''''字段名转换处理完毕

        ''''''''''''''''''''''''''''HtZh'''''''''''''''''处理组合关系的转换'''''''''''''''''''''''''''
        Dim ZHname As String()
        Dim eZhValue As String()


        '字段对应英文
        ZHname = {"并且", "或者"}
        eZhValue = {"and", "or"}

        '加到下拉框中
        CmbZH1.Items.AddRange(ZHname)
        CmbZH2.Items.AddRange(ZHname)
        CmbZH1.Items.Add("")
        CmbZH2.Items.Add("")

        '添加到hashtable
        For t As Integer = 0 To ZHname.Count - 1
            HtZh.Add(ZHname(t), eZhValue(t))
        Next

    End Sub

    '查询
    Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
        '清除单元格
        MyDataGrid.DataSource = Nothing '清空表格


        '先判断是否选择了条件,如果没有选择条件提示
        If CmbZD1.SelectedIndex < 0 OrElse CmbCZ1.SelectedIndex < 0 OrElse txtQuery1.Text.ToString = "" Then
            MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
            Exit Sub
        End If

        '查询前的非空判断
        Dim UserInfo As String() '定义字符数组

        '单条件查询
        If (CmbZH1.SelectedIndex < 0 Or CmbZH1.SelectedIndex = 2) And (CmbZH2.SelectedIndex < 0 Or CmbZH2.SelectedIndex > 1) Then
            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString.Trim, CmbCZ1.SelectedItem.ToString.Trim, txtQuery1.Text.ToString.Trim}
            '2个条件查询
        ElseIf ((CmbZH2.SelectedIndex < 0 Or CmbZH2.SelectedIndex > 1) And (CmbZH1.SelectedIndex >= 0 And CmbZH1.SelectedIndex < 2)) Then

            '强制选择下一行
            If CmbZD2.SelectedIndex < 0 OrElse CmbCZ2.SelectedIndex < 0 OrElse txtQuery2.Text.ToString = "" Then
                MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
                Exit Sub
            End If


            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString, CmbCZ1.SelectedItem.ToString, txtQuery1.Text.ToString, HtZh(CmbZH1.SelectedItem).ToString, HtZD(CmbZD2.SelectedItem).ToString, CmbCZ2.SelectedItem.ToString, txtQuery2.Text.ToString}

        Else    '3条件查询

            If CmbZD3.SelectedIndex < 0 OrElse CmbCZ3.SelectedIndex < 0 OrElse txtQuery3.Text.ToString = "" Then
                MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
                Exit Sub
            End If

            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString.Trim, CmbCZ1.SelectedItem.ToString.Trim, txtQuery1.Text.ToString.Trim, HtZh(CmbZH1.SelectedItem).ToString.Trim, HtZD(CmbZD2.SelectedItem).ToString.Trim, CmbCZ2.SelectedItem.ToString.Trim, txtQuery2.Text.ToString.Trim, HtZh(CmbZH2.SelectedItem).ToString.Trim, HtZD(CmbZD3.SelectedItem).ToString.Trim, CmbCZ3.SelectedItem.ToString.Trim, txtQuery3.Text.ToString.Trim}
        End If


        '查询
        Dim ColWorkInfo As New BLL.ColWorkInfoBLL  '定义B层
        Dim mylist As New List(Of Entity.TeaInfo)   '查询到的集合

        mylist = ColWorkInfo.ChkColWorkInfo(UserInfo)

        If IsNothing(mylist) Then '如果没有查询到
            MsgBox("没有查询到符合条件的记录,请重新输入!", vbOKOnly, "温馨提示")
            Exit Sub

        End If

        MyDataGrid.DataSource = mylist '绑定数据源



    End Sub

    '退出
    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
        Me.Dispose()

    End Sub

    
    '组合关系一确定下面能否使用
    Private Sub CmbZH1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbZH1.SelectedIndexChanged
        If CmbZH1.SelectedItem.ToString <> "" Then
            '下面一栏能用
            CmbZD2.Enabled = True
            CmbCZ2.Enabled = True
            txtQuery2.Enabled = True
            CmbZH2.Enabled = True

        Else
            CmbZD2.Enabled = False
            CmbCZ2.Enabled = False
            txtQuery2.Enabled = False
            CmbZH2.Enabled = False
        End If

    End Sub

    '组合关系二确定下面能否使用
    Private Sub CmbZH2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbZH2.SelectedIndexChanged
        If CmbZH2.SelectedItem.ToString <> "" Then
            '下面一栏能用
            CmbZD3.Enabled = True
            CmbCZ3.Enabled = True
            txtQuery3.Enabled = True
        Else
            CmbZD3.Enabled = False
            CmbCZ3.Enabled = False
            txtQuery3.Enabled = False
        End If

    End Sub
End Class




B层太简单,不写了,直接看D层:



  ''' <summary>
    ''' 查询操作员工作记录
    ''' </summary>
    ''' <param name="userInfo"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ChkUserWorkInfo(ByVal userInfo As String()) As List(Of Entity.TeaInfo) Implements IDAL.IteaInfoDAO.ChkUserWorkInfo

        ReDim Preserve userInfo(0 To 13)

        Dim mySqlHelper As New SQLHelper '定义sqlHelper工具类
        Dim strSQL As String    '定义SQL查询语句
        Dim dt As New DataTable '定义返回表
        Dim mylist As New List(Of Entity.TeaInfo) '定义转换后的集合

        strSQL = "Pro_ZHQuery"
        Dim sqlParams As SqlParameter() = {New SqlParameter("@ChkTable", "T_TeaInfo"), New SqlParameter("@cboFieldA", userInfo(0)), New SqlParameter("@cboOperatorA", userInfo(1)), New SqlParameter("@txtConditionA", userInfo(2)), New SqlParameter("@cboRelationA", userInfo(3)), New SqlParameter("@cboFieldB", userInfo(4)), New SqlParameter("@cboOperatorB", userInfo(5)), New SqlParameter("@txtConditionB", userInfo(6)), New SqlParameter("@cboRelationB", userInfo(7)), New SqlParameter("@cboFieldC", userInfo(8)), New SqlParameter("@cboOperatorC", userInfo(9)), New SqlParameter("@txtConditionC", userInfo(10))}

        dt = mySqlHelper.ExecSelect(strSQL, CommandType.StoredProcedure, sqlParams)

        If dt.Rows.Count <= 0 Then  '如果没有查询到,返回空
            Return Nothing

        End If

        mylist = Entity.EntityConverter.convertToList(Of Entity.TeaInfo)(dt)
        Return mylist

    End Function






     还有后台的存储过程,在所有的组合查询里面,因为参数原型一样,所以就只用了一个存储过程,表明也是在调用存储过程的时候传入的:




ALTER procedure [dbo].[Pro_ZHQuery]
	
	@ChkTable varchar(10),
	
	@cboFieldA varchar(10),  
	@cboOperatorA varchar(10),  
	@txtConditionA varchar(10), 
	 
	@cboRelationA varchar(10)='and', 
	 
	@cboFieldB varchar(10)='1',  
	@cboOperatorB varchar(10)='=',  
	@txtConditionB varchar(10)='1',  
	
	@cboRelationB varchar(10)='and', 
	 
	@cboFieldC varchar(10)='1',  
	@cboOperatorC varchar(10)='=',  
	@txtConditionC varchar(10)='1'
AS  
	declare @TempSql varchar(500)--临时存放sql语句  
	--CHAR(32)是空格,CHAR(39)单引号  
	
	BEGIN  
	set @TempSql='select * from '+ @ChkTable +' where '+CHAR(32)  
	+@cboFieldA+@cboOperatorA+CHAR(39)+@txtConditionA+CHAR(39)+  
	CHAR(32)+@cboRelationA+CHAR(32)+  
	@cboFieldB+@cboOperatorB+CHAR(39)+@txtConditionB+CHAR(39)+  
	+CHAR(32)+@cboRelationB+CHAR(32)  
	+@cboFieldC+@cboOperatorC+CHAR(39)+@txtConditionC+CHAR(39)  
	execute (@TempSql)  
	  
	END  

   


     整体看起来,前台,也就是界面,冗余太多了,3个窗体每个窗体的代码都粘了一遍。


   

     这次,做之前首先规划了一下到底该怎么改?首先来看看哪里有多余的:前台:除了加载的hashtable内容和显示的内容不一样,别的地方区别很小;后台,D层中,因为三个组合查询用到的D层方法只是返回值不同,所以,返回值这里可以用list (of T)代替,这样,前台后台冗余就少多了。



    首先,看看D层是怎么改的:


    



    

   当B层调用的时候,动态传入T类型,这样三个组合查询窗体就共用一个D层方法了。


    接下来是U层,我们将重复的地方抽出来:




Public Class Form1
    Public HtZD As New Hashtable   '定义处理字段名转换的hashtable
    Public HtZh As New Hashtable '定义处理组合关系转换的hashtable

    '处理条件关系转换
    Public ZDname() As String
    Public eZdValue() As String

    '处理组合关系转换
    Public ZHname As String()
    Public eZhValue As String()


  

    '字段转换,将用户选择的条件转换成数据库中可查询的字段
    Public MustOverride Sub ChangeIntoDBName()




    '窗体加载
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load



        MyDataGrid.AutoGenerateColumns = False '禁止自动加载数据源

        Call ChangeIntoDBName() '调用字段转换函数


        ''''''''''''''''''''''''''''''处理数据库中列名的转换
        '加载中文字段到下拉列表框中
        CmbZD1.Items.AddRange(ZDname)
        CmbZD2.Items.AddRange(ZDname)
        CmbZD3.Items.AddRange(ZDname)

        '中文为key,英文为value添加到hashtable
        For i As Integer = 0 To ZDname.Count - 1
            HtZD.Add(ZDname(i), eZdValue(i))
        Next
        '''''数据库中列名转换处理完毕




        ''''''''''''''''''''''''''''HtZh'''''''''''''''''处理组合关系的转换''''''''''''''''''''''''''

        '字段对应英文
        ZHname = {"并且", "或者"}
        eZhValue = {"and", "or"}
        '加到下拉框中
        CmbZH1.Items.AddRange(ZHname)
        CmbZH2.Items.AddRange(ZHname)
        CmbZH1.Items.Add("")
        CmbZH2.Items.Add("")

        '添加到hashtable
        For t As Integer = 0 To ZHname.Count - 1
            HtZh.Add(ZHname(t), eZhValue(t))
        Next

    End Sub


    '退出
   


    '组合关系一确定下面能否使用
    Private Sub CmbZH1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbZH1.SelectedIndexChanged
        If CmbZH1.SelectedItem.ToString <> "" Then
            '下面一栏能用
            CmbZD2.Enabled = True
            CmbCZ2.Enabled = True
            txtQuery2.Enabled = True
            CmbZH2.Enabled = True

        Else
            CmbZD2.Enabled = False
            CmbCZ2.Enabled = False
            txtQuery2.Enabled = False
            CmbZH2.Enabled = False
        End If

    End Sub

    '组合关系二确定下面能否使用
    Private Sub CmbZH2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbZH2.SelectedIndexChanged
        If CmbZH2.SelectedItem.ToString <> "" Then
            '下面一栏能用
            CmbZD3.Enabled = True
            CmbCZ3.Enabled = True
            txtQuery3.Enabled = True
        Else
            CmbZD3.Enabled = False
            CmbCZ3.Enabled = False
            txtQuery3.Enabled = False
        End If

    End Sub

    '查询
    Public Overridable Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
        '清除单元格
        MyDataGrid.DataSource = Nothing '清空表格


        '先判断是否选择了条件,如果没有选择条件提示
        If CmbZD1.SelectedIndex < 0 OrElse CmbCZ1.SelectedIndex < 0 OrElse txtQuery1.Text.ToString = "" Then
            MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
            Exit Sub
        End If

        '查询前的非空判断
        Dim UserInfo As String() '定义字符数组

        '单条件查询
        If (CmbZH1.SelectedIndex < 0 Or CmbZH1.SelectedIndex = 2) And (CmbZH2.SelectedIndex < 0 Or CmbZH2.SelectedIndex > 1) Then

            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString.Trim, CmbCZ1.SelectedItem.ToString.Trim, txtQuery1.Text.ToString.Trim}

            '2个条件查询
        ElseIf ((CmbZH2.SelectedIndex < 0 Or CmbZH2.SelectedIndex > 1) And (CmbZH1.SelectedIndex >= 0 And CmbZH1.SelectedIndex < 2)) Then

            '强制选择下一行
            If CmbZD2.SelectedIndex < 0 OrElse CmbCZ2.SelectedIndex < 0 OrElse txtQuery2.Text.ToString = "" Then
                MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
                Exit Sub
            End If


            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString, CmbCZ1.SelectedItem.ToString, txtQuery1.Text.ToString, HtZh(CmbZH1.SelectedItem).ToString, HtZD(CmbZD2.SelectedItem).ToString, CmbCZ2.SelectedItem.ToString, txtQuery2.Text.ToString}

        Else    '3条件查询

            If CmbZD3.SelectedIndex < 0 OrElse CmbCZ3.SelectedIndex < 0 OrElse txtQuery3.Text.ToString = "" Then
                MsgBox("请选择查询条件!", vbOKOnly, "温馨提示")
                Exit Sub
            End If

            UserInfo = {HtZD(CmbZD1.SelectedItem).ToString.Trim, CmbCZ1.SelectedItem.ToString.Trim, txtQuery1.Text.ToString.Trim, HtZh(CmbZH1.SelectedItem).ToString.Trim, HtZD(CmbZD2.SelectedItem).ToString.Trim, CmbCZ2.SelectedItem.ToString.Trim, txtQuery2.Text.ToString.Trim, HtZh(CmbZH2.SelectedItem).ToString.Trim, HtZD(CmbZD3.SelectedItem).ToString.Trim, CmbCZ3.SelectedItem.ToString.Trim, txtQuery3.Text.ToString.Trim}
        End If

       


    End Sub



    Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click

    End Sub
End Class

   (需要注意的是:如果使用的是继承的窗体,即添加窗体的时候选择的是继承的窗体,那么控件的初始化写在form_load里面; 但是如果是类继承模板窗体,需要将控件的初始化写在父窗体的sub new里面)


   对比下,主要改动就是:



 


   然后在继承的窗体中,实现加载九个下拉框的文字记载:

 

  


 

       


         但是,查询按钮的click时间还要在父类方法的基础上进行一些修改:click时间里面在我们没有用模板的时候,放的是清空数据源,判断选了几个条件,然后才是调用B层查询接着显示结果,所以,我们需要前面的两个步骤,对后面的调用B层进行一个多态,所以,如上所示:



<span style="font-size:18px;"></span><pre name="code" class="vb"> Public Overridable Sub btnQuery_Click

 




        然后在子窗体中重写:

     

    


   


      至此,基本的窗体的继承算是实现了,但是,对于学生基本信息查询的窗体,这个窗体是在模板窗体的基础上多出两个button来的:



   

     

    




      多出了修改按钮和退出按钮,好吧,那就在窗体加载的时候用代码添加两个按钮吧:






           

     

  

目录
相关文章
|
4月前
|
数据安全/隐私保护 C++
C++ 类的继承与派生
C++ 类的继承与派生
45 0
|
Java 程序员 编译器
面向对象编程的组合、多态、抽象类的基本介绍(一)
面向对象编程的组合、多态、抽象类的基本介绍
面向对象编程的组合、多态、抽象类的基本介绍(一)
|
编译器
面向对象编程的组合、多态、抽象类的基本介绍(二)
面向对象编程的组合、多态、抽象类的基本介绍
面向对象编程的组合、多态、抽象类的基本介绍(二)
|
编译器 C++
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(上)
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(上)
123 0
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(上)
|
Linux C++
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(下)
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(下)
109 0
【C++】多态(万字详解) —— 条件 | 虚函数重写 | 抽象类 | 多态的原理(下)
|
安全 Java 程序员
Java面向对象之组合与多态
本篇文章是上一篇包和继承文章的后续篇,针对面向对象编程的组合、多态、抽象类与接口方面内容的总结分享,希望各位小主们认真浏览,一定会受益多多哟
89 0
Java面向对象之组合与多态
|
Java 编译器 C++
【C++要笑着学】继承 | 子类默认成员函数 | 单继承与多继承 | 钻石继承 | 虚拟继承 | 继承和组合(二)
本系列 C++ 教学博客的基础知识已经告一段落了,下面的章节我会先把面向对象三大特性讲完,然后穿插一些数据结构的教学以方便我们继续讲解 STL 的 map 和 set。对于面向对象三大特性 —— 封装、继承、多态,我们已经在之前讲解过封装了,本章将开始讲解继承,详细探讨多继承引发的钻石继承问题,并用虚继承解决钻石继承问题。阅读本章需要掌握访问限定符以及默认成员函数的知识,如果阅读过程中感到有些许生疏建议先去复习一下。
118 0
【C++要笑着学】继承 | 子类默认成员函数 | 单继承与多继承 | 钻石继承 | 虚拟继承 | 继承和组合(二)
|
安全 程序员 C++
【C++要笑着学】继承 | 子类默认成员函数 | 单继承与多继承 | 钻石继承 | 虚拟继承 | 继承和组合(一)
本系列 C++ 教学博客的基础知识已经告一段落了,下面的章节我会先把面向对象三大特性讲完,然后穿插一些数据结构的教学以方便我们继续讲解 STL 的 map 和 set。对于面向对象三大特性 —— 封装、继承、多态,我们已经在之前讲解过封装了,本章将开始讲解继承,详细探讨多继承引发的钻石继承问题,并用虚继承解决钻石继承问题。阅读本章需要掌握访问限定符以及默认成员函数的知识,如果阅读过程中感到有些许生疏建议先去复习一下。
73 0
【C++要笑着学】继承 | 子类默认成员函数 | 单继承与多继承 | 钻石继承 | 虚拟继承 | 继承和组合(一)
|
编译器
面向对象——继承与派生
面向对象——继承与派生
127 0
面向对象——继承与派生
|
Java C++
C++继承与派生解析(继承、重载/转换运算符、多重继承、多态、虚函数/纯虚函数、抽象类)
C++继承与派生解析(继承、重载/转换运算符、多重继承、多态、虚函数/纯虚函数、抽象类)
159 0