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

      

          上次个人版机房收费做的时候,组合查询这里做的不好,没有抽出模板,导致感觉有很多冗余,这次自己挑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来的:

   

     

    

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

           

     

  

时间: 2024-09-30 04:49:47

组合查询——继承与多态的小练习的相关文章

Java中继承、多态、重载和重写介绍_java

什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型.继承是面向对象的三个基本特征--封装.继承.多态的其中之一,我们在使用JAVA时编写的每一个类都是在继承,因为在JAVA语言中,java.lang.Object类是所有类最根本的基类(或者叫父类.超类),如果

初学者对于java继承、多态,子类对象的内存分配的一些问题,百度了好多,但感觉没有系统的,在此提问,希望前辈们传到授业解惑

问题描述 由于是初学者,所以有些表述可能有误,都只是自己的一些理解.我是纯初学者,看过两个星期的C++,之前也学过C.感觉看C++的时候,更容易去理解C++中的面向对象技术的实现,但看JAVA的时候,可能隔着一层虚拟机,有些实现很难理解.第一个问题:我了解到一个对象里面,隐含了一个引用this,可以用this来特别地引用本对象的成员或者函数,然后还有一个super关键字,书上说这个关键字不是一个引用,但怎么看都感觉这个super是一个指向本对象的父类类型的引用.我想问这个super到底是什么,如

蛙蛙推荐:asp中的多条件组合查询实现

条件|组合查询 <!-- 蛙蛙推荐:asp中的多条件组合查询实现多条件组合查询在很多地方都很有用,本文用一个简单的例子来实现一种组合查询在示例之前请确保你安装有sqlserver2000及其默认数据库NorhtWind.代码非常直观,加上关键部分我做了注释,所以很容易理解.需要注意的几个问题就是:1.在字符串连接的时候注意两个需要连接的串中第二个串的开头第一个字符应该打一个空格,这样不至于两个串的首尾相连成一个单词.2.righ的left函数取出的结构区分大小写,如果你字符串里用的是'and',

组合查询以及拼接字符串

首先,什么情况下要用到组合查询呢?总的来说,有两种情况:一是在单个查询中从不同的表返回类似结构的数据:二是对单个表执行多个查询,按单个查询返回数据.在这里,我们说的组合查询是指第二种情况,即要查询的表是固定的,查询条件是不定的并且有多个查询条件. 从例子来看, 例如,输入相应的查询条件 1.教师不等于"0" 2.机器号等于"yang" 两个条件是"与"的关系,我们可以很容易的写出它的sql语句 select * from T_Worklog_In

Scala学习:使用组合与继承

组合与继承是利用其它现存类定义新类的两个方法.如果你接下来的工作主要是代码重用,通常你应 采用组合而不是继承.只有继承受脆基类问题之苦,这种情况你可能会无意中通过改变超类而破坏了子 类. 关于继承关系你可以问自己一个问题,是否它建模了一个is-a关系.Meyers,<Effective C++> [ Mey91]例如,说ArrayElement是Element是合理的.你能问的另一个问题是,是否客户想要把子类类型 当作超类类型来用.Eckel,<Thinking in Java>[

高并发低基数多字段任意组合查询的优化

1.问题 首先解释一下这个标题里出现的"低基数多字段任意组合查询"指什么东西.这里是指满足下面几个条件的查询: 1. 检索条件中涉及多个字段条件的组合 2. 这些字段的组合是不确定的 3. 每个单独字段的选择性都不好 这种类型的查询的使用场景很多,比如电商的商品展示页面.用户会输入各种不同查询条件组合:品类,供应商,品牌,促销,价格等等...,最后往往还要对结果进行排序和分页. 这类问题令人头疼的地方在于: 1. 记录数量众多,如果进行全表扫描性能低下无法满足高并发访问的要求. 2.

PgSQL · 应用案例 · GIN索引在任意组合查询中的应用

背景 很多人小时候都有一个武侠梦,独孤求败更是金庸武侠小说里的一位传奇人物. 纵横江湖三十馀载,杀尽仇寇奸人,败尽英雄豪杰,天下更无抗手,无可奈何,惟隐居深谷,以雕为友. 呜呼,生平求一敌手而不可得,诚寂寥难堪也. 独孤老前辈的佩剑描写非常有意思,从使用的佩剑,可以看出一个人的武功修为. 第一柄是一柄青光闪闪的无名利剑.「凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋.」 第二柄是紫薇软剑,「三十岁前所用,误伤义士不祥,乃弃之深谷.」 第三柄是玄铁重剑,「重剑无锋,大巧不工,四十岁之前恃之横行天下

继LINQ动态组合查询PredicateExtensions讲解

        在LINQ动态组合查询中我留下了一个问题就是PredicateExtensions.在这里很简单不需要什么多的基础只要比会And.Or逻辑运算数学知识就够了. 先贴上代码好分析:   代码 public static class PredicateExtensions     {         public static Expression<Func<T, bool>> True<T>() { return f => true; }      

Java封装、继承、多态三大特征的理解_java

首先先简单的说一下其3大特性的定义: 封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别.将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员.封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员.封装的基本要求是: 把所有的属性私有化,对每个属性提供getter和setter方法,如果有一个带参的