在机房收费系统中有三个窗体功能涉及到组合查询。vb版的组合查询和.net+三层架构版的组合查询还是有一些区别的。虽然有区别,但是,核心不变——拼接字符串。
为什么说组合查询是一个小难点?
1,它与普通查询的区别:普通查询只要一条含有参数的sql语句即可.例如根据卡号查余额(其中@CardID为参数).Dim sql As String = "selectCardID ,StudentInfo.StuID,StuName,Sex,Department,Grade,Class,Explian,Cash,CardInfo.Status from StudentInfo,CardInfo where StudentInfo.StuID=CardInfo.StuID And CardInfo.CardID=@CardIDand CardInfo.Status='使用'"
(1)可以说参数@CardID的值是确定的,直接将txtCardID中的内容传递过来即可。而组合查询的参数不止一个,并且是动态的,选择不同的查询条件,就会有不同的参数,并且查询条件不止一个。
(2)并且(普通的查询(按上例)操作符为“=”,而组合查询操作符不确定(=、>、<、<>);
(3)普通查询只有一个查询条件,组合查询有多条,并且关系不确定(或、与)
2,两层的组合查询和三层的组合查询又不一样?
原因:三层的sql语句需要参数传递,两层无需参数,直接在本层完成
我的设计:1,没有点击第一个组合关系的话,后两排控件不可用.即,只有第一个查询条件有效;2,点击了第一个组合关系,但是组合关系框内没有选内容,即便后两排填了查询条件也无效;3,点击了第一个组合关系,并且选择了其中一种关系(或/与),如果第二排没有填写查询条件或条件输入不完整则会提示“请将查询条件输入完整!”,此时前两个查询条件输入有效;4,第二个组合关系,同理。
看起来很复杂,其实就是:选择的组合关系框数,决定有效的查询条件数。条件输入不完整时,提示。
我还增加了修改信息功能,有意者可以私下讨论。
看代码:
设计到的View_StuInfo视图:
UI层:
Public Class FrmManageStuInfo '点击“查询”按钮 Private Sub btCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCheck.Click Dim combinQuery_m As New Model.combinQuery Dim combinQuery_bll As New BLL.combinQuery_BLL Dim ds As DataSet Dim table As String = "View_StuInfo" '视图View_StuInfo Dim arrayCtr(8) As Control '定义控件数组 '给数组赋值 arrayCtr(0) = cmbField1 '字段1控件 arrayCtr(1) = cmbField2 '字段2控件 arrayCtr(2) = cmbField3 '字段3控件 arrayCtr(3) = cmbOperate1 '操作符1控件 arrayCtr(4) = cmbOperate2 '操作符2控件 arrayCtr(5) = cmbOperate3 '操作符3控件 arrayCtr(6) = txtContent1 '查询内容1控件 arrayCtr(7) = txtContent2 '查询内容2控件 arrayCtr(8) = txtContent3 '查询内容3控件 '当组合关系1=空,并且组合关系2不可用;或者组合关系1!=空,并且组合关系2不可用时 If (cmbAndOr1.Text = "" And cmbAndOr2.Enabled = False) Or (Not cmbAndOr1.Text = "" And cmbAndOr2.Enabled = True) Then '调用UI层combinQuery_UI类中的TxtIsNull()方法,判断除两个组合关系控件外的所有可用控件是否为空 If combinQuery_UI.TxtIsNull(arrayCtr) Then '除两个组合关系控件外,如果存在内容为空的控件,则提示“请将查询条件输入完整” MessageBox.Show("请将查询条件输入完整!") Exit Sub End If End If '给参数赋值 combinQuery_m.CmbField1 = cmbField1.Text.Trim() '将查询条件字段1的值赋给实体combinQuery_m的字段1CmbField1属性 combinQuery_m.CmbField2 = cmbField2.Text.Trim() '将查询条件字段2的值赋给实体combinQuery_m的字段2CmbField2属性 combinQuery_m.CmbField3 = cmbField3.Text.Trim() '将查询条件字段3的值赋给实体combinQuery_m的字段3CmbField3属性 combinQuery_m.CmbOperate1 = cmbOperate1.Text.Trim() '将操作符1的值赋给实体combinQuery_m的操作符1CmbOperate1属性 combinQuery_m.CmbOperate2 = cmbOperate2.Text.Trim() '将操作符2的值赋给实体combinQuery_m的操作符2CmbOperate2属性 combinQuery_m.CmbOperate3 = cmbOperate3.Text.Trim() '将操作符3的值赋给实体combinQuery_m的操作符3CmbOperate3属性 combinQuery_m.TxtContent1 = txtContent1.Text.Trim() '将查询内容1的值赋给实体combinQuery_m的查询内容1TxtContent1属性 combinQuery_m.TxtContent2 = txtContent2.Text.Trim() '将查询内容2的值赋给实体combinQuery_m的查询内容2TxtContent2属性 combinQuery_m.TxtContent3 = txtContent3.Text.Trim() '将查询内容3的值赋给实体combinQuery_m的查询内容3TxtContent3属性 combinQuery_m.CmbAndOr1 = cmbAndOr1.Text.Trim() '将组合关系1的值赋给实体combinQuery_m的组合关系1CmbAndOr1属性 combinQuery_m.CmbAndOr2 = cmbAndOr2.Text.Trim() '将组合关系2的值赋给实体combinQuery_m的组合关系2CmbAndOr2属性 '调用Model层combinQuery类的StudentInfoField()方法,返回界面中每个查询字段中对应的表中的每个字段名,以实体形式保存 combinQuery_m = Model.combinQuery.StudentInfoField(combinQuery_m) '调用BLL层CombinQuery_BLL()方法,返回数据集ds ds = combinQuery_bll.CombinQuery_BLL(table, combinQuery_m) 'DataGridView1控件绑定数据源 DataGridView1.DataSource = ds.Tables("NewTable") DataGridView1.Columns(0).HeaderText = "学号" DataGridView1.Columns(1).HeaderText = "卡号" DataGridView1.Columns(2).HeaderText = "姓名" DataGridView1.Columns(3).HeaderText = "性别" DataGridView1.Columns(4).HeaderText = "系别" DataGridView1.Columns(5).HeaderText = "年级" DataGridView1.Columns(6).HeaderText = "班级" DataGridView1.Columns(7).HeaderText = "金额" DataGridView1.Columns(8).HeaderText = "状态" DataGridView1.Columns(9).HeaderText = "备注" 'DataGridView1控件的列绑定数据表中的列 For i = 0 To ds.Tables("NewTable").Rows.Count - 1 DataGridView1.Columns(i).DataPropertyName = ds.Tables("NewTable").Columns(i).ToString() Next i btModify.Enabled = True End Sub '点击“组合关系1”控件 Private Sub cmbAndOr1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmbAndOr1.Click '输入第二个条件的控件们可用 cmbField2.Enabled = True cmbOperate2.Enabled = True txtContent2.Enabled = True cmbAndOr2.Enabled = True End Sub ' 窗体加载 Private Sub FrmManageStuInfo_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '窗体加载时,将DataGridView控件设为只读的,即,不可编辑。只有当点击“修改”按钮时,才可编辑,将ReadOnly=False DataGridView1.ReadOnly = True '“修改”按钮和“保存修改”按钮不可用。当 点击“查询”按钮,并且有查询内容(查询内容不为空)时,“修改”按钮才可用 btModify.Enabled = False btSaveModify.Enabled = False '输入第二个条件的控件们不可用 cmbField2.Enabled = False cmbOperate2.Enabled = False txtContent2.Enabled = False cmbAndOr2.Enabled = False '输入第三个条件的控件们不可用 cmbField3.Enabled = False cmbOperate3.Enabled = False txtContent3.Enabled = False End Sub '选择“组合关系1”中值时 Private Sub cmbAndOr1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAndOr1.SelectedIndexChanged '输入第二个条件的控件们可用 cmbField2.Enabled = True cmbOperate2.Enabled = True txtContent2.Enabled = True cmbAndOr2.Enabled = True End Sub '选择“组合关系2”中值时 Private Sub cmbAndOr2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbAndOr2.SelectedIndexChanged '输入第三个条件的控件们可用 cmbField3.Enabled = True cmbOperate3.Enabled = True txtContent3.Enabled = True End Sub
BLL层:
Public Class combinQuery_BLL ''' <summary> ''' 组合查询 ''' </summary> ''' <param name="combinQuery"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function CombinQuery_BLL(ByVal table As String, ByVal combinQuery As Model.combinQuery) As DataSet Dim combinQuery_da As New DAL.combinQuery_DA Dim ds As DataSet ds = combinQuery_da.CombinQuery_DA(table, combinQuery) Return ds End Function End Class
DAL层:
'组合查询类 Public Class combinQuery_DA ''' <summary> ''' 组合查询 ''' </summary> ''' <param name="table"></param> ''' <param name="combinQuery"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function CombinQuery_DA(ByVal table As String, ByVal combinQuery As Model.combinQuery) As DataSet 'sql语句。调用Model层combinQuery类的方法CombinQuerySql()方法,返回sql语句 Dim sql As String = Model.combinQuery.CombinQuerySql(table, combinQuery) Dim ds As DataSet '定义Dataset变量 '调用ExecuteDataset()方法,返回数据集ds ds = New SqlHelper.SqlHelper().ExecuteDataSet(sql, CommandType.Text) Return ds End Function
实体层:
定义组合查询为实体类,并将“字段1”、“字段2”、”“字段3”、“操作符1”、“操作符2”、“操作符3”、“组合关系1”、“组合关系2” 设为实体类combinQuery的属性。
'组合查询信息类 Public Class combinQuery '字段1 Private _cmbField1 As String Public Property CmbField1() As String Get Return _cmbField1 End Get Set(ByVal value As String) _cmbField1 = value End Set End Property '字段2 Private _cmbField2 As String Public Property CmbField2() As String Get Return _cmbField2 End Get Set(ByVal value As String) _cmbField2 = value End Set End Property '字段3 Private _cmbField3 As String Public Property CmbField3() As String Get Return _cmbField3 End Get Set(ByVal value As String) _cmbField3 = value End Set End Property '操作符 Private _cmbOperate1 As String Public Property CmbOperate1() As String Get Return _cmbOperate1 End Get Set(ByVal value As String) _cmbOperate1 = value End Set End Property '操作符2 Private _cmbOperate2 As String Public Property CmbOperate2() As String Get Return _cmbOperate2 End Get Set(ByVal value As String) _cmbOperate2 = value End Set End Property '操作符3 Private _cmbOperate3 As String Public Property CmbOperate3() As String Get Return _cmbOperate3 End Get Set(ByVal value As String) _cmbOperate3 = value End Set End Property '查询内容1 Private _txtContent1 As String Public Property TxtContent1() As String Get Return _txtContent1 End Get Set(ByVal value As String) _txtContent1 = value End Set End Property '查询内容2 Private _txtContent2 As String Public Property TxtContent2() As String Get Return _txtContent2 End Get Set(ByVal value As String) _txtContent2 = value End Set End Property '查询内容3 Private _txtContent3 As String Public Property TxtContent3() As String Get Return _txtContent3 End Get Set(ByVal value As String) _txtContent3 = value End Set End Property '组合关系1 Private _cmbAndOr1 As String Public Property CmbAndOr1() As String Get Return _cmbAndOr1 End Get Set(ByVal value As String) _cmbAndOr1 = value End Set End Property '组合关系2 Private _cmbAndOr2 As String Public Property CmbAndOr2() As String Get Return _cmbAndOr2 End Get Set(ByVal value As String) _cmbAndOr2 = value End Set End Property
以下方法,用Select case语句给“字段1”、“字段2”、”“字段3”、“操作符1”、“操作符2”、“操作符3”、“组合关系1”、“组合关系2” 赋表的字段值。
''' <summary> ''' 将查询字段(例如:卡号)对应于StudentInfo表中的字段(例如:CardID),将操作符对应于关系运算符,将组合关系(或/与)对应于逻辑运算符(Or/And) ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function StudentInfoField(ByVal combinQuery As combinQuery) As combinQuery 'Dim combinQuery As New combinQuery '实例化实体类combinQuery '查询字段1 Select Case (combinQuery.CmbField1) Case "卡号" combinQuery.CmbField1 = "CardID" Case "学号" combinQuery.CmbField1 = "StuID" Case "姓名" combinQuery.CmbField1 = "StuName" Case "性别" combinQuery.CmbField1 = "Sex" Case "系别" combinQuery.CmbField1 = "Department" Case "年级" combinQuery.CmbField1 = "Grade" Case "班级" combinQuery.CmbField1 = "Class" End Select '查询字段2 Select Case combinQuery.CmbField2 Case "卡号" combinQuery.CmbField2 = "CardID" Case "学号" combinQuery.CmbField2 = "StuID" Case "姓名" combinQuery.CmbField2 = "StuName" Case "性别" combinQuery.CmbField2 = "Sex" Case "系别" combinQuery.CmbField2 = "Department" Case "年级" combinQuery.CmbField2 = "Grade" Case "班级" combinQuery.CmbField2 = "Class" End Select '查询字段3 Select Case combinQuery.CmbField3 Case "卡号" combinQuery.CmbField3 = "CardID" Case "学号" combinQuery.CmbField3 = "StuID" Case "姓名" combinQuery.CmbField3 = "StuName" Case "性别" combinQuery.CmbField3 = "Sex" Case "系别" combinQuery.CmbField3 = "Department" Case "年级" combinQuery.CmbField3 = "Grade" Case "班级" combinQuery.CmbField3 = "Class" End Select '操作符1 Select Case combinQuery.CmbOperate1 Case "=" combinQuery.CmbOperate1 = "=" Case ">" combinQuery.CmbOperate1 = ">" Case "<" combinQuery.CmbOperate1 = "<" Case "<>" combinQuery.CmbOperate1 = "<>" End Select '操作符2 Select Case combinQuery.CmbOperate2 Case "=" combinQuery.CmbOperate2 = "=" Case ">" combinQuery.CmbOperate2 = ">" Case "<" combinQuery.CmbOperate2 = "<" Case "<>" combinQuery.CmbOperate2 = "<>" End Select '操作符3 Select Case combinQuery.CmbOperate3 Case "=" combinQuery.CmbOperate3 = "=" Case ">" combinQuery.CmbOperate3 = ">" Case "<" combinQuery.CmbOperate3 = "<" Case "<>" combinQuery.CmbOperate3 = "<>" End Select '组合关系1 Select Case combinQuery.CmbAndOr1 Case "或" combinQuery.CmbAndOr1 = "Or" Case "与" combinQuery.CmbAndOr1 = "And" End Select '组合关系2 Select Case combinQuery.CmbAndOr2 Case "或" combinQuery.CmbAndOr2 = "Or" Case "与" combinQuery.CmbAndOr2 = "And" End Select Return combinQuery End Function
以下方法是拼接sql语句的方法。其中字符串类型的参数table的作用实现了代码复用性,因为不止在管理学生信息一个窗体是组合查询,还有查询教师工作记录,查询学生上机状态时也是组合查询. 通过table参数传递个窗体涉及到的表明,从而都可用次方法,代码复用.
''' <summary> ''' 生成组合查询sql语句——拼接sql字符串 ''' </summary> ''' <param name="table">所需查询的表</param> ''' <param name="combinQuery">combinQuery实体</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function CombinQuerySql(ByVal table As String, ByVal combinQuery As combinQuery) As String '首先,第一个查询条件有效 Dim sql As String = "select * from " & table & " where " & combinQuery.CmbField1 & " " & combinQuery.CmbOperate1 & " " & combinQuery.TxtContent1 If combinQuery.CmbAndOr1 = "" Then '如果第一个组合关系为空,则第一个查询条件有效 Return sql Else '如果第一个组合关系不为空,则前两个查询条件有效 sql = sql & " " & combinQuery.CmbAndOr1 & " " & combinQuery.CmbField2 & " " & combinQuery.CmbOperate2 & " " & combinQuery.TxtContent2.Trim() If combinQuery.CmbAndOr2 = "" Then '如果第一个组合关系不为空,第二个组合关系为空,则仅仅前两个查询条件有效 Return sql Else '如果第一二组合关系不为空,则三个查询条件均有效 sql = sql & " " & combinQuery.CmbAndOr2 & " " & combinQuery.CmbField3 & " " & combinQuery.CmbOperate3 & " " & combinQuery.TxtContent3.Trim() Return sql End If End If If combinQuery.CmbAndOr1 <> "" And combinQuery.CmbAndOr2 = "" Then '如果第一个组合关系不为空,第二个组合关系为空,则前两个查询条件有效 sql = sql & " " & combinQuery.CmbAndOr1 & " " & combinQuery.CmbField2 & " " & combinQuery.CmbOperate2 & " " & combinQuery.TxtContent2.Trim() ElseIf combinQuery.CmbAndOr1 <> "" And combinQuery.CmbAndOr2 <> "" Then '如果第一个组合关系和第二个组合关系均不为空,则三个查询条件有效 sql = sql End If End Function
End Class