機房重構之組合查詢
一、前言
這一次的組合查詢自己還是收貨很大的,組合查詢有幾個頁面的功能大致都是一樣的,第一次機房我是怎麼做的呢?我完成了一個視窗,其他的基本上都是複製貼上來的。當時自己是很開心啊,不用敲這麼多,粘一下多好啊~其實呢,現在自己明白了,如果自己貼過來的程式碼有一處有問題,那麼自己貼了幾處就要修改幾次,現在想想這樣好嗎?於是,今天要說的模板方法就出爐了~
二、模板方法
2.1思考模板方法
之前自己在大話中對於設計模式的理解一直是停留在很遙遠的一個地方,不知道這些東西可以幹啥,這次真的用到了模板方法,心裡還真的有些興奮呢~回想當時設計模式中為啥提到了模板方法呢?不同的學生在做試卷,試卷是一樣的,只是每個學生的答案是不一樣的。我們當時怎麼做的呢?將相同的部分抽象到父類中去實現,不同的地方我們可以寫成虛方法,延伸到子類中去實現。所以組合查詢我們可以類比過來~
2.2 相同的窗體
組合查詢一類的窗體,操作員工作記錄,學生資訊維護,學生上機統計資訊:,這樣的話,我們可以將相同的內容抽象出來提取到父窗體中實現,將不同的內容抽象成一個虛方法,讓各個子類去實現自己的部分。
三、舉例組合查詢
3.1 父窗體
父窗體中我們將都可以用到的公共控制元件建好,當然如果自己一時沒有建全也是沒有關係的,因為我們每次重新生成的時候都會更新一下,也會泛化到子類中去。父窗體中自己寫了兩個虛方法,一個是將欄位轉換成資料庫列名的一個方法,另一個是返回自己對應的資料庫表名的方法,這樣是為了方便自己以後更好的做判斷。程式碼如下:
#region 虛方法
//將查詢的內容轉換成資料庫中的列名稱
public virtual string ToName(string combo)
{
return "";
}
//獲得資料庫名稱
protected virtual string Getdbtable()
{
return "";
}
#endregion
private void btOk_Click(object sender, EventArgs e)
{
//每次點選按鈕前先清空dgv
dataGridView1.DataSource = null;
//1 沒有組合的查詢判空
//限制輸入不能為空
if (cmbRelation1.Text == "")
{
Control[] arrcontrol = new Control[3];
arrcontrol[0] = cmbFields1;
arrcontrol[1] = cmbOperator1;
arrcontrol[2] = txtContext1;
//呼叫函式判斷控制元件中的內容是否為空
bool falg;
falg = EmptyUI.ISsomeEmpty(arrcontrol);
if (falg == true)
{
MessageBox.Show("內容填寫不完整,請核對後再查詢!");
enGroupQuery = null;
return;
}
}
else
{
if (cmbRelation2.Text == "")
{
//2 開始第一個組合的查詢判空
Control[] arrcontrol2 = new Control[6];
arrcontrol2[0] = cmbFields1;
arrcontrol2[1] = cmbOperator1;
arrcontrol2[2] = txtContext1;
arrcontrol2[3] = cmbFields2;
arrcontrol2[4] = cmbOperator2;
arrcontrol2[5] = txtContext2;
bool falg;
falg = EmptyUI.ISsomeEmpty(arrcontrol2);
if (falg == true)
{
MessageBox.Show("內容填寫不完整,請核對後再查詢!");
enGroupQuery = null;
return;
}
}
else
{ //開始第三個條件的組合查詢
Control[] arrcontrol3 = new Control[9];
arrcontrol3[0] = cmbFields1;
arrcontrol3[1] = cmbOperator1;
arrcontrol3[2] = txtContext1;
arrcontrol3[3] = cmbFields2;
arrcontrol3[4] = cmbOperator2;
arrcontrol3[5] = txtContext2;
arrcontrol3[6] = cmbFields3;
arrcontrol3[7] = cmbOperator3;
arrcontrol3[8] = txtContext3;
//EmptyUI.ISsomeEmpty(arrcontrol3);
bool falg;
falg = EmptyUI.ISsomeEmpty(arrcontrol3);
if (falg == true)
{
MessageBox.Show("內容填寫不完整,請核對後再查詢!");
enGroupQuery = null;
return;
}
}
}
//將引數傳遞給實體
enGroupQuery = new Entity.GroupQuery();
enGroupQuery.fileds1 = ToName(cmbFields1.Text); //這裡呼叫了重寫虛方法的內容
enGroupQuery.fileds2 = ToName(cmbFields2.Text);
enGroupQuery.fileds3 = ToName(cmbFields3.Text);
enGroupQuery.Operator1 = cmbOperator1.Text;
enGroupQuery.Operator2 = cmbOperator2.Text;
enGroupQuery.Operator3 = cmbOperator3.Text;
enGroupQuery.Context1 = txtContext1.Text.Trim();
enGroupQuery.Context2 = txtContext2.Text.Trim();
enGroupQuery.Context3 = txtContext3.Text.Trim();
enGroupQuery.Relation1 = ToName(cmbRelation1.Text);
enGroupQuery.Relation2 = ToName(cmbRelation2.Text);
enGroupQuery.table = Getdbtable();
}
3.2 子窗體
不得不說VS現在很強大了,我們可以通過建立子窗體來繼承父窗體。我們可以提高多少效率啊~如下是自己建立泛化子窗體的方法:
好的,這時跟父窗體一樣的窗體就建好了:
這裡一定要悄悄告訴一件事,有的時候你會遇到,子窗體上的控制元件不能使用,為啥呢,這是父窗體中許可權設定的問題,我們將Modifiers修改為Protected,這個問題也就不是什麼問題了~子窗體中的程式碼是如何寫的呢?不要著急,我們一點一點的來。
//重寫轉換成資料庫認識的字串
public override string ToName(string combo)
{
//return base.ToName(combo);
switch (combo)
{
case"卡號":
return "cardno";
case"學號":
return "studentno";
case"姓名":
return "studentname";
case "上機日期":
return "logindate";
case "上機時間":
return "logintime";
case "下機日期":
return "offdate";
case "下機時間":
return "offtime";
case "消費金額":
return "consumeTime";
case "餘額":
return "Money";
default :
return "";
}
}
//重寫查詢表的名稱,這裡我們查詢的是line ,
protected override string Getdbtable()
{
return "line";
}
private void btOk_Click(object sender, EventArgs e)
{
if (enGroupQuery == null)
{
return;
}
else
{
//呼叫子類的查詢,返回不同的查詢結果
DataTable LgroupQuery = new DataTable();
Facade.GroupQueryFacade GroupQuery = new Facade.GroupQueryFacade();
LgroupQuery = GroupQuery.GroupQuery(enGroupQuery);
if (LgroupQuery.Rows.Count > 0)
{
dataGridView1.DataSource = LgroupQuery;
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.Columns[10].HeaderText = "消費時間";
dataGridView1.Columns[11].HeaderText = "消費金額";
dataGridView1.Columns[12].HeaderText = "餘額";
dataGridView1.Columns[13].HeaderText = "狀態";
dataGridView1.Columns[14].HeaderText = "機器號";
}
else
{
MessageBox.Show("沒有記錄", "提示");
}
}
}
3.3D層的實現
本來寫道這裡就該告一段落了,不過還是想補充一下,組合查詢在我們寫D層的時候,無論你是用的sql語句還是儲存過程,都時沒有問題,我們注意一點就是sql語句的拼接。要告訴自己,那些引數傳到D層來的時候,已經做了判空處理了,我們只需要考慮如何從資料庫中將他們找出來就可以了。無論時找幾條語句,想想我們基本的語句,“select * from table where ~”新增上邏輯關係就是“and”“or”。
四、結語
組合查詢下來自己最大的感受時設計模式的厲害之處,不愧是架構師必備的一門課程。加上了設計模式,我們程式碼的複用性提高了,不再是一味的複製貼上。這樣維護起來也變得高效很多。在模板方法中也在慢慢體會抽象的意思,不斷的瞭解。