机房重构——组合查询

时间:2022-09-16 11:05:26

    在重构的过程中发现有好多窗体是很相似的,设计模式这时候就派上用场了,模板方法可以很好的实现功能同时也减少代码量。

    模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中模板方法使得子类可以不改变一个算法结构几个重定义该算法的某些特定步骤。

    结构图:

    机房重构——组合查询

   实践:

 机房重构——组合查询

   部分代码:

    U层:

Public Class FrmGropQuery

Protected EGroup As New Entity.GroupQueryEntity '实例化一个新的实体对象

'窗体加载

Private Sub FrmGropQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'窗体加载时,给字段、操作符、组合关系赋值
'加载组合关系
ComRelation1.Items.Add("与")
ComRelation1.Items.Add("或")

ComRelation2.Items.Add("与")
ComRelation2.Items.Add("或")

'给操作符赋值
ComOperation1.Items.Add(">")
ComOperation1.Items.Add("<")
ComOperation1.Items.Add("=")
ComOperation1.Items.Add("<>")

ComOperation2.Items.Add(">")
ComOperation2.Items.Add("<")
ComOperation2.Items.Add("=")
ComOperation2.Items.Add("<>")

ComOperation3.Items.Add(">")
ComOperation3.Items.Add("<")
ComOperation3.Items.Add("=")
ComOperation3.Items.Add("<>")

'窗体加载后,后两行文本框不能用
ComFields2.Enabled = False
ComOperation2.Enabled = False
txtContext2.Enabled = False

ComFields3.Enabled = False
ComOperation3.Enabled = False
txtContext3.Enabled = False
End Sub

Private Sub BtnQuery_Click(sender As Object, e As EventArgs) Handles BtnQuery.Click
'先将DataGridview中清空
DataGridView1.DataSource = Nothing

'判断文本框、组合框是否为空
'第一个组合关系为空时,第一行的内容均不能为空
If ComRelation1.Text = "" Then
If ComFields1.Text = "" Or ComOperation1.Text = "" Or txtContext1.Text = "" Then
MsgBox("第一行查询条件不能为空,请完善", , "提示")
Exit Sub
End If
End If

'第一个组合关系文本框不为空,则判断前两行不能为空
If ComRelation1.Text <> "" Then
If ComFields1.Text = "" Or ComOperation1.Text = "" Or txtContext1.Text = "" Or ComFields2.Text = "" Or ComOperation2.Text = "" Or txtContext2.Text = "" Then
MsgBox("所输入的查询条件不能为空,请完善", , "提示")
Exit Sub
End If
End If

'第二个组合关系文本框不为空,判断所有的不为空
If ComRelation2.Text <> "" Then
If ComFields1.Text = "" Or ComOperation1.Text = "" Or txtContext1.Text = "" Or ComFields2.Text = "" Or ComOperation2.Text = "" Or txtContext2.Text = "" Or ComFields3.Text = "" Or ComOperation3.Text = "" Or txtContext3.Text = "" Then
MsgBox("所输入的查询条件不能为空,请完善", , "提示")
Exit Sub
End If
End If

'给实体赋值(在实体层新建一个实体类)
EGroup.Fields1 = GetDBName(ComFields1.Text.Trim())
EGroup.Fields2 = GetDBName(ComFields2.Text.Trim())
EGroup.Fields3 = GetDBName(ComFields3.Text.Trim())

EGroup.Operation1 = ComOperation1.Text.Trim()
EGroup.Operation2 = ComOperation2.Text.Trim()
EGroup.Operation3 = ComOperation3.Text.Trim()

EGroup.Context1 = txtContext1.Text.Trim()
EGroup.Context2 = txtContext2.Text.Trim()
EGroup.Context3 = txtContext3.Text.Trim()

EGroup.Relation1 = GetDBName(ComRelation1.Text.Trim())
EGroup.Relation2 = GetDBName(ComRelation2.Text.Trim())
EGroup.GetList = GetList()

Dim faca As New Facade.GroupQueryFacade
Dim dt As New DataTable
dt = faca.Query(EGroup)

If (dt.Rows.Count = 0) Then
MsgBox("没有符合条件的记录", , "提示")
Exit Sub
Else
Call Dview()

End If
End Sub

' 定义虚函数GetDBName,获取不同数据库的字段名
Protected Overridable Function GetDBName(ByVal control As String) As String
Return ""
End Function
' 定义虚函数GetList,获取不同数据库的表名
Protected Overridable Function GetList() As String
Return ""
End Function
'定义虚函数Dview,将数据显示到控件中
Protected Overridable Sub Dview()
End Sub
'组合关系框是否有值会影响到下边行能否操作
Private Sub ComRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComRelation1.SelectedIndexChanged
If ComRelation1.Text <> "" Then
ComFields2.Enabled = True
ComOperation2.Enabled = True
txtContext2.Enabled = True
End If
End Sub

Private Sub ComRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComRelation2.SelectedIndexChanged
If ComRelation2.Text <> "" Then
ComFields3.Enabled = True
ComOperation3.Enabled = True
txtContext3.Enabled = True
End If
End Sub

Private Sub BtnOut_Click(sender As Object, e As EventArgs) Handles BtnOut.Click
Call UI.Exportexcel.ExportExcel(DataGridView1)

End Sub

Private Sub Btnclear_Click(sender As Object, e As EventArgs) Handles Btnclear.Click
ComFields1.Text = ""
ComFields2.Text = ""
ComFields3.Text = ""

ComOperation1.Text = ""
ComOperation2.Text = ""
ComOperation3.Text = ""

ComRelation1.Text = ""
ComRelation2.Text = ""

txtContext1.Clear()
txtContext2.Clear()
txtContext3.Clear()

DataGridView1.DataSource = Nothing
End Sub
End Class

   D层:

Imports System.Data.SqlClient
Imports Entity
Imports IDAL
Imports SQLHelper
Public Class SqlserverGroupQueryDAL : Implements IGroupQuery
Private sqlhelper As New SQLHelper.sqlHelper
Public Function Query(user As GroupQueryEntity) As DataTable Implements IGroupQuery.Query
Dim sql As String
'调用存储过程
sql = "PROC_GroupQuery"

'加入参数
Dim paras As SqlParameter() = {New SqlParameter("@Fields1", user.Fields1),
New SqlParameter("@Fields2", user.Fields2),
New SqlParameter("@Fields3", user.Fields3),
New SqlParameter("@Operation1", user.Operation1),
New SqlParameter("@Operation2", user.Operation2),
New SqlParameter("@Operation3", user.Operation3),
New SqlParameter("@Context1", user.Context1),
New SqlParameter("@Context2", user.Context2),
New SqlParameter("@Context3", user.Context3),
New SqlParameter("@Relation1", user.Relation1),
New SqlParameter("@Relation2", user.Relation2),
New SqlParameter("@GetList", user.GetList)}
Dim dt As DataTable
dt = sqlhelper.ExecSelect(sql, CommandType.StoredProcedure, paras)
Return dt
End Function
End Class
   B层

Public Class GroupQueryBLL
Function Query(ByVal user As Entity.GroupQueryEntity) As DataTable
Dim fty As New Factory.GroupQueryFactory
Dim IGroup As IDAL.IGroupQuery
Dim dt As DataTable

IGroup = fty.CreateGroupQuery
dt = IGroup.Query(user)
Return dt
End Function
End Class
   外观层:

Public Class GroupQueryFacade
Function Query(ByVal user As Entity.GroupQueryEntity) As DataTable
Dim GQBll As New BLL.GroupQueryBLL
Dim table As DataTable
table = GQBll.Query(user)
Return table
End Function
End Class
   存储过程:

CREATE PROCEDURE [dbo].[PROC_GroupQuery]
--加入参数
@Fields1 varchar(10),
@Fields2 varchar(10),
@Fields3 varchar(10),

@Operation1 varchar(10),
@Operation2 varchar(10),
@Operation3 varchar(10),

@Context1 varchar(20),
@Context2 varchar(20),
@Context3 varchar(20),

@Relation1 varchar(10),
@Relation2 varchar(10),
@GetList varchar(20) --获取表的名称

AS
declare @TempSql varchar(500)--临时存放sql语句
BEGIN
SET @TempSql='SELECT * FROM '+ @GetList +' WHERE ' + @Fields1 + @Operation1 + char(39) + @Context1 + char(39)
if @Relation1 != '' --第一个组合关系文本框不为空
BEGIN
SET @TempSql=@TempSql+@Relation1+CHAR(32)+ @Fields2 + @Operation2 +CHAR(39) + @Context2+CHAR(39)
if @Relation2 != '' --第二个组合关系文本框不为空
BEGIN
SET @TempSql=@TempSql+@Relation2 + CHAR(32)+ @Fields3 + @Operation3 + CHAR(39)+@Context3+CHAR(39)
END
END
EXECUTE(@TempSql)
END


  以操作员工作记录为例:

   U层代码

Imports System.Collections '引入哈希表
Public Class FrmOperatorWorkLog

Private Sub FrmOperatorWorkLog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Text = "操作员工作记录" '表名

Dim haField As New Hashtable '定义处理字段名转换的hashtable

'使用哈希表进行数据库字段进行转换
Dim FieldName() As String
Dim FieldValue() As String

'数据库中的字段对应相应的中文
FieldName = {"教师", "级别", "登录日期", "登录时间", "注销日期", "注销时间", "机器名", "状态"}
FieldValue = {"userID", "[level]", "loginDate", "loginTime", "logoutDate", "logoutTime", "computer", "status"}

'放到Field字段中
ComFields1.Items.AddRange(FieldName)
ComFields2.Items.AddRange(FieldName)
ComFields3.Items.AddRange(FieldName)

'中文为key,英文为value添加到hashtable
For i As Integer = 0 To FieldName.Count - 1
haField.Add(FieldName(i), FieldValue(i))
Next
End Sub

'重写获得表名方法
Protected Overrides Function GetList() As String
Return "T_WorkLogInfo"
End Function

'重写转换成数据库字段方法
Protected Overrides Function GetDBName(control As String) As String
Select Case (control)
Case "教师"
Return "userID"
Case "级别"
Return "[level]"
Case "登录日期"
Return "loginDate"
Case "登录时间"
Return "loginTime"
Case "注销日期"
Return "logoutDate"
Case "注销时间"
Return "logoutTime"
Case "机器名"
Return "computer"
Case "状态"
Return "status"
Case Else
Return ""
End Select
End Function

Protected Overrides Sub Dview()
'每次数据查询清空表
DataGridView1.DataSource = Nothing

'表格控件绑定数据源字段
'调用外观,进行传递参数
Dim fac As New Facade.GroupQueryFacade
Dim dt As New DataTable

dt = fac.Query(EGroup)

If dt.Rows.Count = 0 Then
MsgBox("没有记录,请重新进行查询!", vbExclamation, "警告")
DataGridView1.DataSource = Nothing
Else
DataGridView1.DataSource = dt
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.AllowUserToAddRows = False
End If
End Sub
End Class
   总结:用了模板方法感觉方便了好多,但这也只是功能的实现有一些地方需要进一步优化!