C#桌面办公应用-工资管理系统系列七
接前文工资管理系统系列六,本文将介绍C# winform应用程序中的查询模块功能。其中,就包括了综合、模糊查询以及分页查询;值得说明的是,综合查询,其实就是多个条件组合起来的组合查询啦,只不过我换了个不严谨的称呼罢了!组合多个条件并采用模糊查询的方法实现查询功能;而对于分页查询,我想,参与过企业的项目或者是一些实用的项目的博友而言,都不会陌生,就像我一样,我是搞java开发的,公司用的数据库是mysql,所以对于项目中前端页面使用的分页查询我是再熟悉不过了,这个等改天有空我也写篇博文介绍介绍我们公司的项目采用的异步请求分页查询。好了,下面就介绍介绍这两个小功能吧!
对于组合条件、模糊查询,我认为,其实核心在于SQL,比如我在工资管理系统中采用的是MS SQL Server,所以查询的SQL语句是这样子的:
select id,name,address,age from tb_employee where name like '%AA%' and address like '%BB%'
上面的AA 和 BB即为需要从前端获取的数据库字段name和address分别对应的变量!---其实,这就是本质啦,对于分页查询其实也是如此(这一点我是自己悟出来的,以至于后来有时候我本想在网上找一个分页插件,但遇到很多麻烦,最后干脆就自己制作一个分页控件了!!嘻嘻,没办法,“把我惹毛了就是这种下场”)!
下面,以上一篇博文介绍的工资管理系统的员工管理模块为例,下面,就实现员工管理模块的查询功能吧!员工的model以及数据库对应的数据库表已经在前文设计好了!
首先是界面的设计与实现:
页面其他部分的内容是什么已在前文介绍过了!下面是“员工查询”按钮事件代码(其中,也可以在某一个查询条件输入框中输入信息后按“回车键”查询,即我已经实现了“回车查询”的功能)
//员工查询事件
private void buttonQuery_Click(object sender, EventArgs e)
{
try
{
isButtonQuery = true;
String empName = textBoxEmpName.Text.Trim();
String empPart = textBoxEmpPart.Text.Trim();
String empCardNo = textBoxEmpCardNo.Text.Trim();
String empJobtype = textBoxEmpJobType.Text.Trim();
String empSex = comboBoxEmpSex.Text.Trim();
cmmPage.PageNo = 1;
cmmPage.PageSize = pageSize;
String strEmployeeSelectSQL = "select top "+cmmPage.PageSize+" empId as '员工编号',loginName as '登录用户名',powerName as '用户权限',empName as '员工姓名',age as '年龄',sex as '性别',partName as '所属部门',idCardNo as '身份证号',jobType as '职位类型',jobDate as '入职时间',imagePosition as '图片位置',tb_employee.memo as '备注信息' from tb_employee,tb_powerType,tb_part where tb_employee.powerId=tb_powerType.powerId and tb_employee.partID=tb_part.partID and empName like '%"+empName+"%' and sex like '%"+empSex+"%' and partName like '%"+empPart+"%' and idCardNo like '%"+empCardNo+"%' and jobType like '%"+empJobtype+"%' and empId not in (select top "+cmmPage.Start+" empId from tb_employee order by empId)order by empId";
String getQueryCountSQL = "select COUNT(*) from tb_employee,tb_powerType,tb_part where tb_employee.powerId=tb_powerType.powerId and tb_employee.partID=tb_part.partID and empName like '%" + empName + "%' and sex like '%" + empSex + "%' and partName like '%" + empPart + "%' and idCardNo like '%" + empCardNo + "%' and jobType like '%" + empJobtype + "%'";
recordCount = employeeService.getCount(getQueryCountSQL);
pageCount = commonMessage.getTotalPage(pageSize, recordCount);
bindPaginationQuery(strEmployeeSelectSQL,cmmPage,recordCount, pageCount, sender, e);
this.textBoxCurrentPage.Text = "1";
if (dataGridViewEmployeeInfo.Rows.Count == 0)
{
clearEmployeeInfo();
}
}
catch (System.Exception ex)
{
MessageBox.Show("查询部门出错: \n"+ex.Message, "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
}
}
//回车查询
private void textBoxEmpName_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttonQuery_Click(sender, e);
}
}
//回车查询
private void comboBoxEmpSex_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttonQuery_Click(sender, e);
}
}
//回车查询
private void textBoxEmpPart_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttonQuery_Click(sender, e);
}
}
//回车查询
private void textBoxEmpCardNo_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttonQuery_Click(sender, e);
}
}
//回车查询
private void textBoxEmpJobType_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
buttonQuery_Click(sender, e);
}
}
而“重置查询”事件对应的代码:
//重置查询条件
private void buttonReset_Click(object sender, EventArgs e)
{
resetQueryInfo();
}
//重置查询信息
private void resetQueryInfo()
{
textBoxEmpName.Text = "";
textBoxEmpPart.Text = "";
textBoxEmpCardNo.Text = "";
textBoxEmpJobType.Text = "";
comboBoxEmpSex.Text = null;
}
下面是效果:
下面介绍一下“分页查询”功能,其实分页查询,我自己觉得并没有那么的难,它的本质我觉得最终还是归结于SQL或者jdbc的SQL的书写:不同的数据库有不同的写法,像mysql的limit,oracle的rownumber我都试过,我现在用的是MS SQL Server,主要是Top,其原始的分页语句是这样的:
select top 10 * from tb_employee where empId not in (
select top 0 empId from tb_employee order by empId
)order by empId
其中 top 10:表示的是想取 10 条数据,即每一页想显示10条记录,而0是这样子计算出来的 (1-1)*10,第一个1是第几页的意思,10正是前面的10条记录,得到的结果是“数据记录的开始编号”。原理我不多说了,另外值得说明的是,这种方法的性能是比较底下的!关于MS SQL Server的SQL分页查询,可以参考这篇博文:四种方式实现SQLServer分页查询。
好了,分页查询的效果,可以看上面的图片!
我的实现方式是这样的,将分页的那些属性封装成一个类,这个类的属性包括:pageNo,pageSize,start三个属性,如下所示(我测试过了,是没问题的!)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SMS.cmmMessage
{
//分页封装类
public class CommonPage
{
private long pageNo;
private long pageSize;
private long start;
public long PageNo
{
get { return pageNo; }
set { pageNo = value; }
}
public long PageSize
{
get { return pageSize; }
set { pageSize = value; }
}
public long Start
{
get { return pageSize * (pageNo - 1); }
}
public CommonPage() { }
public CommonPage(long pageNo,long pageSize)
{
this.pageNo = pageNo;
this.pageSize = pageSize;
}
}
}
下面是自主制作的分页控件,丑是丑了点,将就点吧!(注意:上面的1000只不过是个label而已,不是真的数据!)而且,在点击“首页”,“尾页”,“上一页”以及“下一页”的时候,需要注意进行相关操作的判断!
下面是“首页”,“上一页”,“下一页”,“尾页”,“输入第几页并跳转”的事件代码:
//控制“第几页的文本框的输入”只能输入数字
private void textBoxCurrentPage_KeyPress(object sender, KeyPressEventArgs e)
{
cmmUtils.onlyInputDigitNumber(sender, e);
}
//分页查询的跳转
private void toolStripButton1_Click(object sender, EventArgs e)
{
//获取“第几页的那个文本框的数字”
String currPage = textBoxCurrentPage.Text.Trim();
if (currPage=="")
{
return;
}
int currentPage = Convert.ToInt32(currPage);
if (currentPage<=0 || currentPage>pageCount)
{
return;
}
cmmPage.PageNo = currentPage;
cmmPage.PageSize = pageSize;
paginationFunction(cmmPage, sender, e);
}
//在文本框中输入第几页回车可以分页查询
private void textBoxCurrentPage_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
toolStripButton1_Click(sender, e);
}
}
//首页事件
private void buttonFirstPage_Click(object sender, EventArgs e)
{
if (pageCount==0)
{
return;
}
cmmPage.PageNo = 1;
cmmPage.PageSize = pageSize;
paginationFunction(cmmPage, sender, e);
}
//首页(箭头)事件
private void toFirstPage_Click(object sender, EventArgs e)
{
buttonFirstPage_Click(sender, e);
}
//尾页事件
private void buttonLastPage_Click(object sender, EventArgs e)
{
if (pageCount == 0)
{
return;
}
cmmPage.PageNo = pageCount;
cmmPage.PageSize = pageSize;
paginationFunction(cmmPage, sender, e);
}
//尾页(箭头)事件
private void toLastPage_Click(object sender, EventArgs e)
{
buttonLastPage_Click(sender, e);
}
//上一页事件
private void buttonPrePage_Click(object sender, EventArgs e)
{
cmmPage.PageNo = cmmPage.PageNo - 1 <= 0 ? cmmPage.PageNo = 1 : cmmPage.PageNo -= 1;
cmmPage.PageSize = pageSize;
paginationFunction(cmmPage, sender, e);
}
//上一页(箭头)事件
private void toPrePage_Click(object sender, EventArgs e)
{
buttonPrePage_Click(sender, e);
}
//下一页事件
private void buttonNextPage_Click(object sender, EventArgs e)
{
cmmPage.PageNo = cmmPage.PageNo >= pageCount ? cmmPage.PageNo = pageCount : cmmPage.PageNo += 1;
cmmPage.PageSize = pageSize;
paginationFunction(cmmPage, sender, e);
}
//下一页(箭头)事件
private void toNextPage_Click(object sender, EventArgs e)
{
buttonNextPage_Click(sender, e);
}
//分页调用的事件:cmmPage-分页封装类的实例
private void paginationFunction(CommonPage cmmPage,object sender, EventArgs e)
{
try
{
String employeeSQL = "";
if (!isButtonQuery)
{
employeeSQL = "select top " + cmmPage.PageSize + " empId as '员工编号',loginName as '登录用户名',powerName as '用户权限',empName as '员工姓名',age as '年龄',sex as '性别',partName as '所属部门',idCardNo as '身份证号',jobType as '职位类型',jobDate as '入职时间',imagePosition as '图片位置',tb_employee.memo as '备注信息' from tb_employee,tb_powerType,tb_part where tb_employee.powerId=tb_powerType.powerId and tb_employee.partID=tb_part.partID and empId not in (select top " + cmmPage.Start + " empId from tb_employee order by empId)order by empId";
recordCount = employeeService.getCount("select COUNT(*) from tb_employee");
}
else
{
String empName = textBoxEmpName.Text.Trim();
String empPart = textBoxEmpPart.Text.Trim();
String empCardNo = textBoxEmpCardNo.Text.Trim();
String empJobtype = textBoxEmpJobType.Text.Trim();
String empSex = comboBoxEmpSex.Text.Trim();
employeeSQL = "select top " + cmmPage.PageSize + " empId as '员工编号',loginName as '登录用户名',powerName as '用户权限',empName as '员工姓名',age as '年龄',sex as '性别',partName as '所属部门',idCardNo as '身份证号',jobType as '职位类型',jobDate as '入职时间',imagePosition as '图片位置',tb_employee.memo as '备注信息' from tb_employee,tb_powerType,tb_part where tb_employee.powerId=tb_powerType.powerId and tb_employee.partID=tb_part.partID and empName like '%" + empName + "%' and sex like '%" + empSex + "%' and partName like '%" + empPart + "%' and idCardNo like '%" + empCardNo + "%' and jobType like '%" + empJobtype + "%' and empId not in (select top " + cmmPage.Start + " empId from tb_employee order by empId)order by empId";
String getQueryCountSQL = "select COUNT(*) from tb_employee,tb_powerType,tb_part where tb_employee.powerId=tb_powerType.powerId and tb_employee.partID=tb_part.partID and empName like '%" + empName + "%' and sex like '%" + empSex + "%' and partName like '%" + empPart + "%' and idCardNo like '%" + empCardNo + "%' and jobType like '%" + empJobtype + "%'";
recordCount = employeeService.getCount(getQueryCountSQL);
}
pageCount = commonMessage.getTotalPage(cmmPage.PageSize, recordCount);
bindPaginationQuery(employeeSQL,cmmPage,recordCount,pageCount, sender, e);
}
catch (System.Exception ex)
{
MessageBox.Show("分页查询员工信息出错: \n" + ex.Message);
}
}
//绑定分页查询的函数
private void bindPaginationQuery(String sql,CommonPage cmmPage,long totalRecord, long totalPage, object sender, EventArgs e)
{
employeeService.bindSqlResultToDatagridView(dataGridViewEmployeeInfo, sql);
this.labelTotalRecordCount.Text = totalRecord.ToString();
this.labelPageCount.Text = totalPage.ToString();
this.labelCurrentPageRecordTotal.Text = dataGridViewEmployeeInfo.Rows.Count.ToString();
this.textBoxCurrentPage.Text = cmmPage.PageNo.ToString();
}
下面是效果:
(1)下面是初始化加载数据的时候,默认就需要有的分页数据,我这里是10条!另外还能看到总共有多少条数据以及当前有多少条数据等等(这都是我自己想到!)
(2)点击上一页:会自动进行判断,如果已经是首页了,就显示首页!点击下一页:
值得说明的是,分页查询功能的实现必须与综合模糊查询结合在一起,在企业的项目中,也事实如此!
好了,博文就介绍这里了,想与我交流的,可以下面留言!个人QQ:1948831260