JavaEE项目实战(OA系统)之十三_员工管理之一

  JavaEE项目实战(OA系统)之十三_员工管理之一

  之前,我们已经完成了“部门管理”模块的练习,并初步掌握了ssh框架的编程。

  下面,我们再做一个练习即“员工管理”模块,通过这个练习,将进一步熟悉ssh框架。

  页面一,员工列表:


  页面二,员工新增/修改:



  “员工管理”模块重点解决几个关键点,一是部门下拉列表的展示,二是员工列表中如何显示部门名称,三是新增/编辑页面的展示细节。

  一、部门下拉列表的展示

  向数据库中加入如下示例数据:

  部门表:


  员工表:



  1. SQL语句

  我们想让部门下拉列表展示为:


  可是用普通的SQL语句,不管怎么排序,是很难达到这个显示顺序的。

  幸好,Oracle数据库针对树形数据,提供了connect by语法。

  基本语法如下:

select * from tbl_dept
connect by prior dept_id=dept_p_id
start with dept_p_id=0;
  第一行是select,用于指定查询内容。

  第二行是connect by,用于指定连接条件,connect by有点类似于自连接,指定当前记录的一个字段与上一条记录的一个字段连接。其中prior这个单词表示“上一条记录”,它的位置不同,会产生两种效果:从根到叶和从叶到根。

  第三行是start with,用于指定起始条件,从树的哪个位置开始。


  我们以scott用户的emp表为例,emp(员工)表有empno(员工号)和mgr(上级领导的员工号),是典型的树形数据。

  示例1:

select * from scott.emp
connect by prior mgr = empno
start with ename = 'SCOTT';
  查询结果:


  这条语句可以这样解释,connect by prior mgr = empno,即使用上一条记录的“上级领导的员工号”作为当前记录的“员工号”,start with ename = 'SCOTT',表示起始点为名为SCOTT的员工。然后下一个员工,就使用上一条记录的mgr字段作为当前记录的empno,产生的效果是从下级到上级。


  示例2:

select * from scott.emp
connect by prior empno = mgr
start with ename = 'KING';
  查询结果:


  这条语句可以这样解释,connect by prior empno = mgr,即使用上一条记录的“员工号”作为当前记录的“上级领导的员工号”,start with ename = 'KING',表示起始点为名为KING的员工,KING是公司总裁。然后下一个员工,就使用上一条记录的empno字段作为当前记录的mgr,产生的效果是从上级到下级。从上级到下级时,对树的遍历算法使用先序遍历,即先访问根节点,再左树,再右树。


  回到我们的问题,通过下面的SQL语句可以实现目的:

select * from tbl_dept
connect by prior dept_id=dept_p_id
start with dept_p_id=0;

  其中,connect by prior dept_id=dept_p_id,会产生从上级到下级的效果,start with dept_p_id=0,符合条件的起始点会有多个,它们都是一级部门。

  查询结果:



  2. DAO类

  修改一下接口,在接口中添加一个方法:

List<Dept2> getTree();

  这里的Dept2,是一个自定义的实体类,代码如下:

public class Dept2 {
	private int id;
	private String name;
	private int level;

	// getter & setter
	// ...
}

  DAO类的代码如何编写呢?首先,我们要清楚Hibernate的查询有两种,一种使用HQL(Hibernate Query Language,是Hibernate的查询语言,功能很强大),它查询的是实体类;另外,Hibernate也可以用原生的SQL。

  Hibernate进行HQL查询时,使用Query对象:

		Session session = sessionFactory.getCurrentSession();
		Query query = session.createQuery("from Dept");
		return (List<Dept>) query.list();
  上述的connect by语法是Oracle特有的SQL语法,并没有相应的HQL,属于原生的SQL,需要使用Hibernate的SQLQuery对象。

  SQLQuery对象的list方法返回的数据一般是List<Object[]>,是值的数组,不太方便,所以我们要将数据封装成自定义实体的列表:

	public List<Dept2> getTree() {
		String sql = "select dept_id id, dept_name name, level from tbl_dept connect by prior dept_id=dept_p_id start with dept_p_id=0";
		Session session = sessionFactory.getCurrentSession();
		SQLQuery sqlQuery = session.createSQLQuery(sql);
		sqlQuery.addScalar("id", StandardBasicTypes.INTEGER);
		sqlQuery.addScalar("name", StandardBasicTypes.STRING);
		sqlQuery.addScalar("level", StandardBasicTypes.INTEGER);
		sqlQuery.setResultTransformer(Transformers
				.aliasToBean(Dept2.class));
		List<Dept2> list = (List<Dept2>) sqlQuery.list();
		return list;
	}

  在SQL语句中,为字段取别名,别名与自定义实体类的属性一致,然后调用addScalar方法一个个地添加字段,最后调用转换器将结果封装成自定义实体的列表。

  至此,DAO类代码完成。


  3. Action类

  在员工管理的Action类中写一个方法,对列表数据加以处理:

	private void getDeptTree() {
		deptList = deptBiz.getTree();
		for (Dept2 dept : deptList) {
			String name = dept.getName();
			if (dept.getLevel() > 1) {
				name = "└" + name;
			}
			for (int i = 1; i < dept.getLevel(); i++) {
				name = " " + name;
			}
			dept.setName(name);
		}
	}


  4. JSP页面

  要将部门列表展示在下拉框中,JSP页面使用如下代码:

请选择部门: <select id="deptId" name="deptId">
			<option value="0">---请选择部门---</option>
			<c:forEach items="${deptList}" var="dept">
				<option value="${dept.id}"
					<c:if test="${dept.id==deptId}">selected="selected"</c:if>>${dept.name}</option>
			</c:forEach>
		</select>

  最终完成的部门下拉列表的展示效果如下:



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值