一、前言
这一次的组合查询自己还是收货很大的,组合查询有几个页面的功能大致都是一样的,第一次机房我是怎么做的呢?我完成了一个窗口,其他的基本上都是复制粘贴来的。当时自己是很开心啊,不用敲这么多,粘一下多好啊~其实呢,现在自己明白了,如果自己贴过来的代码有一处有问题,那么自己贴了几处就要修改几次,现在想想这样好吗?于是,今天要说的模板方法就出炉了~
二、模板方法
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”。
四、结语
组合查询下来自己最大的感受时设计模式的厉害之处,不愧是架构师必备的一门课程。加上了设计模式,我们代码的复用性提高了,不再是一味的复制粘贴。这样维护起来也变得高效很多。在模板方法中也在慢慢体会抽象的意思,不断的了解。