導讀:在機房重構中,有好些個查詢都是大同小異,最為顯著的就是組合查詢了。怎樣給自己省事兒,相同的東西能不能重復利用,就成了一個現實的問題。第一遍做機房的時候,使用的更多的是:復制+粘貼。學習了設計模式后,可以用模板方法解決。這篇文章,就通過窗體繼承和模板方法,實現組合查詢。
觀點:組合查詢在機房中有3中情況,其實,組合查詢完全可以看到是一種查詢情況。
一、窗體繼承的使用
1,首先建立一個父窗體
2,添加一個新項
3,選擇繼承窗體
4,確定后,一個新的繼承窗體就好了。
二、模板方法的使用
備注:定義一個組合查詢的實體,方便傳參
1,首先在U層寫入基礎方法和傳參
<span style="font-size:18px;">Public Class FrmGroupQueryPublic enGroupQuery As New Model.GroupQueryM '定義一個實體參數Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles btnQuery.Click'第一行組合關系為空If cmbRelation1.Text = "" Then'判斷第一行控件內容是否為空If cmbField1.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation1.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent1.Text = "" ThenMsgBox("請輸入要查詢的內容")End IfEnd If' 當第一個組合關系不為空時 If cmbRelation1.Text <> "" ThenIf cmbField1.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation1.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent1.Text = "" ThenMsgBox("請輸入要查詢的內容")ElseIf cmbField2.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation2.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent2.Text = "" ThenMsgBox("請輸入要查詢的內容")End IfEnd If' 當第二個組合關系不為空時 If cmbRelation2.Text <> "" ThenIf cmbField1.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation1.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent1.Text = "" ThenMsgBox("請輸入要查詢的內容")ElseIf cmbField2.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation2.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent2.Text = "" ThenMsgBox("請輸入要查詢的內容")ElseIf cmbField3.Text = "" ThenMsgBox("請輸入字段名")ElseIf cmbOperation3.Text = "" ThenMsgBox("請輸入操作符")ElseIf txtContent3.Text = "" ThenMsgBox("請輸入要查詢的內容")End IfEnd If'給實體層傳參Dim enGroupQuery As New Model.GroupQueryMenGroupQuery._field1 = GetDBName(cmbField1.Text.Trim())enGroupQuery._field2 = GetDBName(cmbField2.Text.Trim())enGroupQuery._field3 = GetDBName(cmbField3.Text.Trim())enGroupQuery._operate1 = cmbOperation1.Text.Trim()enGroupQuery._operate2 = cmbOperation2.Text.Trim()enGroupQuery._operate3 = cmbOperation3.Text.Trim()enGroupQuery._content1 = txtContent1.Text.Trim()enGroupQuery._content2 = txtContent2.Text.Trim()enGroupQuery._content3 = txtContent3.Text.Trim()enGroupQuery._relation1 = GetDBName(cmbRelation1.Text.Trim())enGroupQuery._relation2 = GetDBName(cmbRelation2.Text.Trim())enGroupQuery.GetTable = GetTable() '通過函數的返回值給參數賦值'給B層GroupQuery方法傳遞參數Dim FGroupQuery As New Facade.GroupQuertFADim table As DataTabletable = FGroupQuery.GroupQuery(enGroupQuery)If table.Rows.Count = 0 ThenMsgBox("沒有記錄,請重新設置查詢條件", vbOKOnly, vbExclamation)DataGridView1.DataSource = NothingElseDataGridView1.DataSource = FGroupQuery.GroupQuery(enGroupQuery)End IfEnd Sub' 定義虛函數GetDBName,獲取不同數據庫的字段名 Protected Overridable Function GetDBName(ByVal control As String) As StringReturn ""End Function' 定義虛函數GetDBName,獲取不同數據庫的表名 Protected Overridable Function GetTable() As StringReturn ""End FunctionPrivate Sub Button2_Click_1(sender As Object, e As EventArgs) Handles btnExit.ClickMe.Close()End Sub'組合關系一不為空后,顯示第二行查詢條件Private Sub cmbRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation1.SelectedIndexChangedcmbField2.Enabled = TruecmbOperation2.Enabled = TruecmbRelation2.Enabled = TruetxtContent2.Enabled = TrueEnd Sub'組合關系二不為空后,顯示第三行查詢條件Private Sub cmbRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation2.SelectedIndexChangedcmbField3.Enabled = TruecmbOperation3.Enabled = TruetxtContent3.Enabled = TrueEnd SubEnd Class</span>
2,在B層,對D層數據庫的查詢結果做出處理
<span style="font-size:18px;">Imports Charge.IDAL
Imports Charge.Model
Public Class GroupQueryBLL''' <summary>''' 根據組合查詢D層的返回結果,判斷是否有值''' </summary>''' <param name="enGroupQuery"></param>''' <returns>沒有值,不返回任何東西,有,就返回信息</returns>''' <remarks></remarks>Public Function GroupQueryStudent(ByVal enGroupQuery As Model.GroupQueryM) As DataTableDim factory As New Factory.CreateFactoryDim IGroupQuery As IGroupQuery = factory.CreateGroupQueryDim table As DataTable = IGroupQuery.GroupQuery(enGroupQuery)'檢查D層返回的數據表中是否有數據If table.Rows.Count = 0 ThenReturn NothingElseReturn tableEnd IfEnd Function
End Class</span>
3,在D層對數據進行查詢
<span style="font-size:18px;">/**********************************************
'類名:SQLGroupQuery
'命名空間:ChargeDAL
'創建時間:2015/1/5 20:58:39
'創建人:HXX
'修改時間:
'修改人:
'版本號:4.0.30319.18449
'說明:實現組合條件的
'版權:HHX
'/**********************************************
Imports System.Data.SqlClient
Imports System.Data
Imports ChargePublic Class SQLGroupQuery : Implements IDAL.IGroupQuery''' <summary>''' 根據設置的條件,進行信息查詢''' </summary>''' <param name="enGroupQuery"></param>''' <returns>返回查詢結果信息的集合</returns>Public Function GroupQuery(enGroupQuery As Model.GroupQueryM) As DataTable Implements IDAL.IGroupQuery.GroupQueryDim strSQL As String = "QueryGroup" '調用存儲過程 Dim prams As SqlParameter() = {New SqlParameter("@cmbField1", enGroupQuery._field1),New SqlParameter("@cmbField2", enGroupQuery._field2),New SqlParameter("@cmbField3", enGroupQuery._field3),New SqlParameter("@cmbOperation1", enGroupQuery._operate1),New SqlParameter("@cmbOperation2", enGroupQuery._operate2),New SqlParameter("@cmbOperation3", enGroupQuery._operate3),New SqlParameter("@txtContent1", enGroupQuery._content1),New SqlParameter("@txtContent2", enGroupQuery._content2),New SqlParameter("@txtContent3", enGroupQuery._content3),New SqlParameter("@cmbRelation1", enGroupQuery._relation1),New SqlParameter("@cmbRelation2", enGroupQuery._relation2),New SqlParameter("@tableName", enGroupQuery.GetTable)} '設置參數Dim MyHelper As New SqlHelperDim table As New DataTabletable = MyHelper.ExecSelect(strSQL, CommandType.StoredProcedure, prams)Return tableEnd Function
End Class</span>
三、在繼承窗體中的應用
在繼承窗體中,需要重寫模板父窗體中的方法,關鍵點有:字段的轉換,數據表的返回。
<span style="font-size:18px;"> Private Sub FrmOperateWorkLog_Activated(sender As Object, e As EventArgs) Handles Me.Activated'避免一個窗體多次打開,或者打開多個操作窗體Dim frm As Form'遍歷打開了的每一個窗體For Each frm In Application.OpenForms'如果當前窗體不是主窗體或者沒有被打開過If frm.Name <> Me.Name And frm.Name <> FrmMain.Name And frm.Name <> FrmLine.Name Then'其他打開的窗體最小化frm.WindowState = 1End IfNextEnd SubPrivate Sub FrmMaintainInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load'給字段賦值cmbField1.Items.AddRange({"教師", "注冊日期", "注冊時間", "注銷日期", "注銷時間", "機器名"})cmbField2.Items.AddRange({"教師", "注冊日期", "注冊時間", "注銷日期", "注銷時間", "機器名"})cmbField3.Items.AddRange({"教師", "注冊日期", "注冊時間", "注銷日期", "注銷時間", "機器名"})cmbOperation1.Items.AddRange({"=", "<", ">", "<>"})cmbOperation2.Items.AddRange({"=", "<", ">", "<>"})cmbOperation3.Items.AddRange({"=", "<", ">", "<>"})cmbRelation1.Items.AddRange({"與", "或"})cmbRelation2.Items.AddRange({"與", "或"})End Sub'重寫獲得表名方法Protected Overrides Function GetTable() As StringenGroupQuery.GetTable = "TC_WorkLogInfo"Return enGroupQuery.GetTable()End Function'重寫轉換成數據庫字段方法Protected Overrides Function GetDBName(control As String) As StringSelect Case (control)Case "教師"Return "UserID"Case "注冊時間"Return "OnTime"Case "注冊日期"Return "OnDate"Case "注銷時間"Return "OffTime"Case "注銷日期"Return "OffDate"Case "機器名"Return "Computer"Case "或"Return "or"Case "與"Return "and"Case ElseReturn ""End SelectEnd Function
End Class
</span>
到這里,利用窗體繼承和模板方法進行組合查詢就算是實現了。
四、應用說明
1,這里的返回類型都是DataTable,如果將其換為List,則就沒有這么簡單了。還需要多寫一步(存儲過程中),就像返回查詢表格的參數一樣,將查詢表格的參數寫到List中的表。
2,這里D層的查詢是通過調用的存儲過程,對存儲過程的使用和理解,將在下一篇博客中詳細說明。不過,在這里可以替換成一種類型,就像是第一次做機房時那樣。例(第一次機房中):
<span style="font-size:18px;">txtSQL = txtSQL & tiaojian(Trim(cobozd1(0).Text)) & Trim(cobocz1(0).Text) & "'" & Trim(txtnr1.Text) & "'" _& " and " _& tiaojian(Trim(cobozd1(1).Text)) & Trim(cobocz1(1).Text) & " '" & Trim(txtnr2.Text) & "'" _& " and " _& tiaojian(Trim(cobozd1(2).Text)) & Trim(cobocz1(2).Text) & " '" & Trim(txtnr3.Text) & "'"</span>
在這里,也可以將存儲過程,換成一般的文本類型查詢。因為是應用的參數賦值,使用字符拼接的方式,將組合查詢的三個情況看做是一種情況,也是可行的。五、個人感想
學以致用,學了還要會用才行。剛開始學了設計模式的時候,真的感受不大。但用上了之后,真的覺得很方便。只是在用的過程中有點艱難,不過,把一個個的問題解決了,最后實現了,感覺真的很良好。