07-03
17
人事部门管理系统(1)
作者:Java伴侣 日期:2007-03-17
很长一段时间来,确切的说是两个多月,从年前开始就没有再过多的写程序。主要精力都投入在这个网站上面了,对于Java编程很少去碰。只是偶尔翻翻《核心技术》,不过是蜻蜓点水。前天本想编写一个米店(Domain)的管理系统为自己用,发现编的很吃力。本觉得瞒简单的东西,突然看来如此复杂。编了两天,决定不再写了。去温习一下从前写过的代码。我觉得,这样的话对我的帮助会很大。
下面介绍我去年11月编写的一套人事部门管理系统,项目用时一周(需求分析2天,美工设计2天,其余时间为代码实现)。如图:
需求文档的地址:http://www.yexu8.com/attachments/month_0703/person_xuqiu.htm
从需求文档可以看出,这个项目的布局是由Tiles框架完成的。我们要作的是首先设计出一个完成的框架布局结构页layout.jsp.然后在其中定义其他页面分布位置。此项目共有四部分组成:siderbar.jsp用来作左侧列表选择,header.jsp用来放置logo,footer.jsp用于作者声明,另外一个至关重要的部分是可变的——随着siderbar.jsp的超链接选择而变。有了这种思想以后就可以写tiles-config了:
<definition name="layout-definition" path="/layout.jsp">
<put name="sidebar" value="sidebar.jsp"></put>
<put name="header" value="header.jsp"></put>
<put name="content"></put>
<put name="footer" value="footer.jsp"></put>
</definition>
从上面可以看出内容是可变的,这段代码是接下来所有代码的父级代码,用于作继承之用。
接下来作一个内容页:
<definition extends="layout-definition" name="index-definition">
<put name="content" value="indexContent.jsp"></put>
</definition>
从name大致可以看出这个是为了index首页来使用的。而在index.jsp页面写入代码
这样即可,其实我们最关心的是列表(siderbar)及其内容(contents)部分。它们之间的互动性是我们使用tiles框架的原因。
列表的第一个超链接是"添加员工":
<html:link page="/link1.do"><font color="#000000" style="text-decoration: none"><bean:message key="link.add.emp"/></font></html:link>
link.add.emp分别对应两份bundle文件——这里使用了中英文国际化。国际化是一种反复的简单劳动,这里就不多作阐述了。我们关心的是link1.do的走向,看sturts-config:
<action path="/link1" parameter="link1" type="companypj.AddEmployeeAction" validate="false">
<forward name="link1_success" path="/link1.jsp">
</forward>
进入AddEmployeeAction
图1-1,AddEmployeeAction全部代码:
public class AddEmployeeAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
DynaValidatorForm empDynForm=(DynaValidatorForm)form;
Log log=LogFactory.getLog("A");
String type=mapping.getParameter();
DataSource ds=getDataSource(request);
if(type.equals("link1"))
{
log.info("return_link1..");
DepartmentBean departmentbean=new DepartmentBean(ds);
Collection onlydep=departmentbean.getOnlyDepartments();//这里转入部门类,取出部门集合
request.getSession().setAttribute(Constants.ONLYDEPARTMENTS_KEY,onlydep);//集合保存,并传入下一页面
return mapping.findForward(Constants_url.RETURN_LINK1_SUCCESS);
}
if(type.equals("link_addemp"))
{
EmployeeBean empbean=new EmployeeBean(ds);
//String address=empDynForm.get("address").toString();
empbean.addEmployee(empDynForm);
return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
}
return null;
}
}
再来看下面的getOnlyDepartments()方法,用于取出部门的方法
public Collection getOnlyDepartments() //只找出所有部门的集合,这个方法多此一举,都是动态数据即时更新的,所有没必要用它,当写着玩了~
{
Collection list=new ArrayList();
Collection departments = this.getDepartments();//跳转
Iterator i = departments.iterator();
while(i.hasNext()) {
DepartmentVO Onlydepartments=(DepartmentVO) i.next();
log.info("Onlydep:"+Onlydepartments.getName());
Onlydepartments.setName(Onlydepartments.getName()); //筛选后重新放入
list.add(Onlydepartments);
}
return list;
}
。。。不看不知道,当初我还写了不少没用的解释,哈哈!注意这里有个跳转,跳转到另一个方法,接着看:
public Collection getDepartments()
{
log.info("提交所有部门数据集合");
return this.getDepartmentsHelper(Constants_sql.DEPARTMENT_ALL_SQL);
}
这个方法也只是为了层次清晰和重用性,接着把一条SQL丢给下面赶事实的方法getDepartmentsHelper():
private Collection getDepartmentsHelper(String sql) //遍历集合 帮助方法
{
Collection list=new ArrayList();
try {
Connection conn=ds.getConnection();
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
DepartmentVO departmentvo=new DepartmentVO();
log.info("取部门数据开始");
departmentvo.setId(rs.getInt("id"));
departmentvo.setName(rs.getString("name"));
departmentvo.setDescription(rs.getString("description"));
log.info(rs.getString("description"));
departmentvo.setLeader(rs.getString("leader"));
departmentvo.setPhone(rs.getString("phone"));
departmentvo.setAddress(rs.getString("address"));
departmentvo.setStarttime(rs.getString("starttime"));
departmentvo.setInfo(rs.getString("info"));
list.add(departmentvo);
log.info("取部门数据结束");
}
conn.close();
stmt.close();
rs.close();
} catch (SQLException ex) {
ex.getMessage();
}
return list;
}
OK,拿到了所有部门的所有信息;回到上面那句:
看来当时我是想作一个优化,减轻页面的负担,而在后台多了下些功夫,现在想来大可不必,不如直接另写一个找差name的SQL语句。。我当时大脑在想些什么哩。。
回到图1-1中的
存入session中,返回到添加员工表单;
箭头所指,就是我们刚才作遍历出来的部门集合位置。
回到了link1.jsp,而在tiles中实际表单位置是CreateEmployee.jsp:
<definition extends="layout-definition" name="link1-definition">
<put name="content" value="return/CreateEmployee.jsp"></put>
</definition>
下面找CreateEmployee.jsp代码,代码太多,我把主要的写上,至于其他部分感兴趣可以去下载我整个项目来看,我提供了下载。
这里是拿到部门集合在表单上的遍历:
<html:select property="department">
<logic:iterate id="onlydep" name="ONLYDEPARTMENTS" type="companypj.DepartmentVO" scope="session">
<option value="<bean:write name="onlydep" property="name"/>">
<bean:write name="onlydep" property="name"/>
</option>
</logic:iterate>
</html:select>
name拿到了集合,type转型成VO以作分类遍历,scope指定去session中拿。
再来看看表单的提交
在struts-config中找到:
<action input="/link1.jsp" name="EmpForm" path="/link_addemp" parameter="link_addemp"
scope="request" type="companypj.AddEmployeeAction" validate="true" >
看到还是转入AddEmployeeAction,图1-1。但是validate="true",表明先要进行表单验证,那么我们就去看一下配置文件validation:
<formset>
<form name="EmpForm">
<field property="name" depends="required">
<arg0 key="label.emp.name"/>
</field>
<field property="age" depends="required">
<arg0 key="label.emp.age"/>
</field>
<field property="salary" depends="required">
<arg0 key="label.emp.salary"/>
</field>
</form>
</formset>
简单的让人觉得可怜哈,都不为空就行!
PS:这里是作得动态表单,而下一个超链接的部门添加是用了静态表单。别的就没有太多差别,思想都一样!
如果验证通过,转入Action中处理,看代码:
if(type.equals("link_addemp"))
{
EmployeeBean empbean=new EmployeeBean(ds);
//String address=empDynForm.get("address").toString();
empbean.addEmployee(empDynForm);
return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
}
addEmployee方法把form接收过去:
public void addEmployee(DynaValidatorForm empDynForm) {
EmployeeVO employeeVO = this.NynaIntoEmp(empDynForm);
String strSQL="{call demo_empadd(?,?,?,?,?,?,?,?,?)}";//存储过程
this.executeEmpHelper(employeeVO, strSQL);
}
这里我作的是一个存储过程:
Create PROCEDURE demo_empadd
@inparam1 varchar(10),@inparam2 varchar(20),@inparam3 int,
@inparam4 varchar(10),@inparam5 varchar(20),@inparam6 varchar(10),
@inparam7 varchar(20),
@inparam8 varchar(10),@inparam9 varchar(40)
AS insert into employee(name,sex,age,salary,department,marriage,address,phone,resume)values
(@inparam1,@inparam2,@inparam3,@inparam4,@inparam5,@inparam6,@inparam7,@inparam8,@inparam9)
GO
接着再转到executeEmpHelper()方法来作实际工作,这时传入了一个VO,和一个存储过程的指令:
private void executeEmpHelper(EmployeeVO employeeVO, String sql) { //帮助方法
try {
Connection conn = ds.getConnection();
java.sql.CallableStatement pstm=conn.prepareCall(sql);
//PreparedStatement pstm = conn.prepareStatement(sql);
log.info("雇员信息开始加入");
pstm.setString(1, employeeVO.getName());
pstm.setString(2, employeeVO.getSex());
pstm.setInt(3, employeeVO.getAge());
pstm.setString(4, employeeVO.getSalary());
pstm.setString(5, employeeVO.getDepartment());
pstm.setString(6, employeeVO.getMarriage());
pstm.setString(7, employeeVO.getAddress());
pstm.setString(8, employeeVO.getPhone());
// log.info("1");
pstm.setString(9, employeeVO.getResume());
// log.info("2");
pstm.executeUpdate();
log.info("雇员信息加入结束");
} catch (SQLException ex) {
}
}
OK,从图1-1中的Action传回一个信号,config接收到
添加完成!
下面介绍我去年11月编写的一套人事部门管理系统,项目用时一周(需求分析2天,美工设计2天,其余时间为代码实现)。如图:
需求文档的地址:http://www.yexu8.com/attachments/month_0703/person_xuqiu.htm
从需求文档可以看出,这个项目的布局是由Tiles框架完成的。我们要作的是首先设计出一个完成的框架布局结构页layout.jsp.然后在其中定义其他页面分布位置。此项目共有四部分组成:siderbar.jsp用来作左侧列表选择,header.jsp用来放置logo,footer.jsp用于作者声明,另外一个至关重要的部分是可变的——随着siderbar.jsp的超链接选择而变。有了这种思想以后就可以写tiles-config了:
复制内容到剪贴板 程序代码
<definition name="layout-definition" path="/layout.jsp">
<put name="sidebar" value="sidebar.jsp"></put>
<put name="header" value="header.jsp"></put>
<put name="content"></put>
<put name="footer" value="footer.jsp"></put>
</definition>
从上面可以看出内容是可变的,这段代码是接下来所有代码的父级代码,用于作继承之用。
接下来作一个内容页:
复制内容到剪贴板 程序代码
<definition extends="layout-definition" name="index-definition">
<put name="content" value="indexContent.jsp"></put>
</definition>
从name大致可以看出这个是为了index首页来使用的。而在index.jsp页面写入代码
复制内容到剪贴板 程序代码
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert definition="index-definition">
</tiles:insert>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert definition="index-definition">
</tiles:insert>
这样即可,其实我们最关心的是列表(siderbar)及其内容(contents)部分。它们之间的互动性是我们使用tiles框架的原因。
列表的第一个超链接是"添加员工":
复制内容到剪贴板 程序代码
<html:link page="/link1.do"><font color="#000000" style="text-decoration: none"><bean:message key="link.add.emp"/></font></html:link>
link.add.emp分别对应两份bundle文件——这里使用了中英文国际化。国际化是一种反复的简单劳动,这里就不多作阐述了。我们关心的是link1.do的走向,看sturts-config:
复制内容到剪贴板 程序代码
<action path="/link1" parameter="link1" type="companypj.AddEmployeeAction" validate="false">
<forward name="link1_success" path="/link1.jsp">
</forward>
进入AddEmployeeAction
图1-1,AddEmployeeAction全部代码:
复制内容到剪贴板 程序代码
public class AddEmployeeAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
DynaValidatorForm empDynForm=(DynaValidatorForm)form;
Log log=LogFactory.getLog("A");
String type=mapping.getParameter();
DataSource ds=getDataSource(request);
if(type.equals("link1"))
{
log.info("return_link1..");
DepartmentBean departmentbean=new DepartmentBean(ds);
Collection onlydep=departmentbean.getOnlyDepartments();//这里转入部门类,取出部门集合
request.getSession().setAttribute(Constants.ONLYDEPARTMENTS_KEY,onlydep);//集合保存,并传入下一页面
return mapping.findForward(Constants_url.RETURN_LINK1_SUCCESS);
}
if(type.equals("link_addemp"))
{
EmployeeBean empbean=new EmployeeBean(ds);
//String address=empDynForm.get("address").toString();
empbean.addEmployee(empDynForm);
return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
}
return null;
}
}
再来看下面的getOnlyDepartments()方法,用于取出部门的方法
复制内容到剪贴板 程序代码
public Collection getOnlyDepartments() //只找出所有部门的集合,这个方法多此一举,都是动态数据即时更新的,所有没必要用它,当写着玩了~
{
Collection list=new ArrayList();
Collection departments = this.getDepartments();//跳转
Iterator i = departments.iterator();
while(i.hasNext()) {
DepartmentVO Onlydepartments=(DepartmentVO) i.next();
log.info("Onlydep:"+Onlydepartments.getName());
Onlydepartments.setName(Onlydepartments.getName()); //筛选后重新放入
list.add(Onlydepartments);
}
return list;
}
。。。不看不知道,当初我还写了不少没用的解释,哈哈!注意这里有个跳转,跳转到另一个方法,接着看:
复制内容到剪贴板 程序代码
public Collection getDepartments()
{
log.info("提交所有部门数据集合");
return this.getDepartmentsHelper(Constants_sql.DEPARTMENT_ALL_SQL);
}
这个方法也只是为了层次清晰和重用性,接着把一条SQL丢给下面赶事实的方法getDepartmentsHelper():
复制内容到剪贴板 程序代码
private Collection getDepartmentsHelper(String sql) //遍历集合 帮助方法
{
Collection list=new ArrayList();
try {
Connection conn=ds.getConnection();
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
DepartmentVO departmentvo=new DepartmentVO();
log.info("取部门数据开始");
departmentvo.setId(rs.getInt("id"));
departmentvo.setName(rs.getString("name"));
departmentvo.setDescription(rs.getString("description"));
log.info(rs.getString("description"));
departmentvo.setLeader(rs.getString("leader"));
departmentvo.setPhone(rs.getString("phone"));
departmentvo.setAddress(rs.getString("address"));
departmentvo.setStarttime(rs.getString("starttime"));
departmentvo.setInfo(rs.getString("info"));
list.add(departmentvo);
log.info("取部门数据结束");
}
conn.close();
stmt.close();
rs.close();
} catch (SQLException ex) {
ex.getMessage();
}
return list;
}
OK,拿到了所有部门的所有信息;回到上面那句:
复制内容到剪贴板 程序代码
Onlydepartments.setName(Onlydepartments.getName()); //筛选后重新放入
看来当时我是想作一个优化,减轻页面的负担,而在后台多了下些功夫,现在想来大可不必,不如直接另写一个找差name的SQL语句。。我当时大脑在想些什么哩。。
回到图1-1中的
复制内容到剪贴板 程序代码
request.getSession().setAttribute(Constants.ONLYDEPARTMENTS_KEY,onlydep);//集合保存,并传入下一页面
存入session中,返回到添加员工表单;
复制内容到剪贴板 程序代码
<forward name="link1_success" path="/link1.jsp">
箭头所指,就是我们刚才作遍历出来的部门集合位置。
回到了link1.jsp,而在tiles中实际表单位置是CreateEmployee.jsp:
复制内容到剪贴板 程序代码
<definition extends="layout-definition" name="link1-definition">
<put name="content" value="return/CreateEmployee.jsp"></put>
</definition>
下面找CreateEmployee.jsp代码,代码太多,我把主要的写上,至于其他部分感兴趣可以去下载我整个项目来看,我提供了下载。
这里是拿到部门集合在表单上的遍历:
复制内容到剪贴板 程序代码
<html:select property="department">
<logic:iterate id="onlydep" name="ONLYDEPARTMENTS" type="companypj.DepartmentVO" scope="session">
<option value="<bean:write name="onlydep" property="name"/>">
<bean:write name="onlydep" property="name"/>
</option>
</logic:iterate>
</html:select>
name拿到了集合,type转型成VO以作分类遍历,scope指定去session中拿。
再来看看表单的提交
复制内容到剪贴板 程序代码
<html:form action="/link_addemp.do" method="POST">
在struts-config中找到:
复制内容到剪贴板 程序代码
<action input="/link1.jsp" name="EmpForm" path="/link_addemp" parameter="link_addemp"
scope="request" type="companypj.AddEmployeeAction" validate="true" >
看到还是转入AddEmployeeAction,图1-1。但是validate="true",表明先要进行表单验证,那么我们就去看一下配置文件validation:
复制内容到剪贴板 程序代码
<formset>
<form name="EmpForm">
<field property="name" depends="required">
<arg0 key="label.emp.name"/>
</field>
<field property="age" depends="required">
<arg0 key="label.emp.age"/>
</field>
<field property="salary" depends="required">
<arg0 key="label.emp.salary"/>
</field>
</form>
</formset>
简单的让人觉得可怜哈,都不为空就行!
PS:这里是作得动态表单,而下一个超链接的部门添加是用了静态表单。别的就没有太多差别,思想都一样!
如果验证通过,转入Action中处理,看代码:
复制内容到剪贴板 程序代码
if(type.equals("link_addemp"))
{
EmployeeBean empbean=new EmployeeBean(ds);
//String address=empDynForm.get("address").toString();
empbean.addEmployee(empDynForm);
return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
}
addEmployee方法把form接收过去:
复制内容到剪贴板 程序代码
public void addEmployee(DynaValidatorForm empDynForm) {
EmployeeVO employeeVO = this.NynaIntoEmp(empDynForm);
String strSQL="{call demo_empadd(?,?,?,?,?,?,?,?,?)}";//存储过程
this.executeEmpHelper(employeeVO, strSQL);
}
这里我作的是一个存储过程:
复制内容到剪贴板 程序代码
Create PROCEDURE demo_empadd
@inparam1 varchar(10),@inparam2 varchar(20),@inparam3 int,
@inparam4 varchar(10),@inparam5 varchar(20),@inparam6 varchar(10),
@inparam7 varchar(20),
@inparam8 varchar(10),@inparam9 varchar(40)
AS insert into employee(name,sex,age,salary,department,marriage,address,phone,resume)values
(@inparam1,@inparam2,@inparam3,@inparam4,@inparam5,@inparam6,@inparam7,@inparam8,@inparam9)
GO
接着再转到executeEmpHelper()方法来作实际工作,这时传入了一个VO,和一个存储过程的指令:
复制内容到剪贴板 程序代码
private void executeEmpHelper(EmployeeVO employeeVO, String sql) { //帮助方法
try {
Connection conn = ds.getConnection();
java.sql.CallableStatement pstm=conn.prepareCall(sql);
//PreparedStatement pstm = conn.prepareStatement(sql);
log.info("雇员信息开始加入");
pstm.setString(1, employeeVO.getName());
pstm.setString(2, employeeVO.getSex());
pstm.setInt(3, employeeVO.getAge());
pstm.setString(4, employeeVO.getSalary());
pstm.setString(5, employeeVO.getDepartment());
pstm.setString(6, employeeVO.getMarriage());
pstm.setString(7, employeeVO.getAddress());
pstm.setString(8, employeeVO.getPhone());
// log.info("1");
pstm.setString(9, employeeVO.getResume());
// log.info("2");
pstm.executeUpdate();
log.info("雇员信息加入结束");
} catch (SQLException ex) {
}
}
OK,从图1-1中的Action传回一个信号,config接收到
复制内容到剪贴板 程序代码
<forward name="link_addemp_ready" path="/link1_add_success.jsp">
添加完成!
评论: 2 | 引用: 0 | 查看次数: 1120
你这个系统是商用吗?如果不是能不能把完整的源码发给我一份。我的邮箱是yuyanshan1@163.com谢谢了
发表评论
这程序并非商用,只是自己练习时所写,至于你说的完整源码。以后我会传到空间上面提供下载,如果真这必要的话—_—||!