手记

EasyUI+JavaWeb奖助学金管理系统[9]-分页显示项目列表

1. 本章任务

已经可以使用学校管理员登录,我们来实现学校管理员的第一个主要功能:管理奖助学金项目。

奖助学金项目是系统的基础档案,需要学校管理员将项目信息建好后,学生才能申请相关项目。

本章首先来实现下分页显示奖学金项目的功能。

2. 构建测试数据

在数据库项目表构建一些测试数据:

INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (1, 'award', '奖学金1', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (2, 'award', '奖学金2', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (3, 'award', '奖学金3', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (4, 'award', '奖学金4', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (5, 'award', '奖学金5', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (6, 'award', '奖学金6', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (7, 'award', '奖学金7', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (8, 'award', '奖学金8', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (9, 'award', '奖学金9', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (10, 'award', '奖学金10', '');
INSERT INTO `scholar-system`.`project`(`id`, `type`, `name`, `about`) VALUES (11, 'help', '助学金11', '');

3. 前端页面开发

3.1 新建页面

新建projectManage.html前端页面,并引入easyui相关的css和js文件。

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title></title>
	<link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css">
	<link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">
	<link rel="stylesheet" type="text/css" href="css/main.css">
	<script type="text/javascript" src="easyui/jquery.min.js"></script>
	<script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>
</head>
<body>
</body>
</html>
3.2 新建数据表格

我们需要通过表格展示项目信息,所以新建数据表格如下:

	<table id="mainTable" title="项目列表" class="easyui-datagrid"
		url="CoreServlet?method=getProjectPage" pagination="true"
		singleSelect="true">
		<thead>
			<tr>
				<th data-options="field:'id'">序号</th>
				<th data-options="field:'type'">类型</th>
				<th data-options="field:'name'">名称</th>
				<th data-options="field:'about'">简介</th>
			</tr>
		</thead>
	</table>

这段代码很关键,我们来仔细解释下。

  1. class="easyui-datagrid",说明当前的表格是easyui的datagrid组件,也就是数据表格。
  2. url="CoreServlet?method=getProjectPage",说明了数据表格请求的数据地址,注意当页面初始化,或者请求页码变化时,数据表格会主动再次请求url指向的地址,并将返回数据加载到表格中。
  3. pagination="true"表示启用分页,启用分页后,每次请求url都会携带当前页码信息,默认会携带page=1 rows=10给后端的Servlet,表示请求第一页,每页展示10行。
  4. singleSelect="true"表示启用单选,每次只能选中1行数据。
  5. <th field="id">序号</th>,这个很有意思,注意有一个field="id",也就是Servlet返回值中键为id的属性对应该列。

根据上面的描述,数据表格会自动请求url,而且还携带分页信息,最强大的是还会将返回数据根据列–属性对应关系显示到数据表格中。

这些动作都是datagrid自动完成的,不需要我们手写ajax方法请求url,然后根据返回值生成table的行。所以easyui是比较完整的封装,用起来比较方便。

4. 返回值封装

在之前的案例中,都是返回Result对象,code表示成功标识,data表示数据域。

但是EasyUI要求返回数据中必须包含total和rows,total表示数据总的条数,rows是数据的集合。EasyUI的数据表格会自动的去分析total和rows的值,然后计算出有多少页,将rows的值显示到数据表格中。

所以我们改造下Result对象,在分页的情况下,可以返回total和rows。注意rows由于可能是各种对象的集合,所以我们直接用T泛型来表示即可。

/**
 * 统一返回结果类
 */
public class Result<T> {
	/**
	 * 0成功 9999失败
	 */
	private int code;
	/**
	 * 提示信息
	 */
	private String msg;
	/**
	 * 返回数据
	 */
	private T data;
	/**
	 * 分页总数
	 */
	private int total;
	/**
	 * 分页数据
	 */
	private T rows;
	// 省略get set
}

5. Servlet返回分页数据

这部分比较简单了,首先在Servlet中获取前端请求的页码page和每页展示行数rows。

	public Result handleRequest(HttpServletRequest request) throws Exception {
		Result result = new Result();
		String method = request.getParameter("method");
		// 请求页码、每页显示行数、总数
		int page = 1, rows = 10, total = 0;
		if (method.contains("Page") == true) {// 当前为分页请求
			// 获取
			String inputPage = request.getParameter("page");
			String inputRows = request.getParameter("rows");
			page = (inputPage == null) ? 1 : Integer.parseInt(inputPage);
			rows = (inputRows == null) ? 10 : Integer.parseInt(inputRows);
		}
		// ......省略部分不相关代码
		// 获取项目分页
		else if (method.equals("getProjectPage")) {
			ProjectDao projectDao = new ProjectDao();
			total = projectDao.getCount();
			result.setTotal(total);
			result.setRows(projectDao.getPage(page, rows));
		}
		return result;
	}

此处解释下:

  1. if (method.contains("Page") == true) {,分页请求时url中都含有Page字样,便于我们后端判断是否分页请求。
  2. total = projectDao.getCount();,封装一个方法返回项目的总数量。
  3. projectDao.getPage(page, rows),封装一个方法,根据页码和每页显示个数返回对应的数据库记录。

6. 封装数据库方法

就是获取条数和指定页记录的方法。

	/**
	 * 获取数量
	 */
	public int getCount() throws Exception {
		Connection conn = ConnectionUtils.getConnection();
		String sql = "select count(id) from project ";
		QueryRunner runner = new QueryRunner();
		Number number = (Number) runner.query(conn, sql, new ScalarHandler());
		int value = number.intValue();
		ConnectionUtils.releaseConnection(conn);
		return value;
	}

	/**
	 * 分页查询
	 */
	public List<Project> getPage(int page, int rows) throws Exception {
		Connection conn = ConnectionUtils.getConnection();
		String sql = "select * from project limit ?,?";
		QueryRunner runner = new QueryRunner();
		Object[] params = { (page - 1) * rows, rows };
		List<Project> projects = runner.query(conn, sql, new BeanListHandler<Project>(Project.class), params);
		ConnectionUtils.releaseConnection(conn);
		return projects;
	}

7. 测试

样式有点丑,我们添加下fitColumns属性让列适应宽度,然后设置下列的宽度比例:

	<table id="mainTable" title="项目列表" class="easyui-datagrid" url="CoreServlet?method=getProjectPage" pagination="true"
		singleSelect="true" fitColumns="true">
		<thead>
			<tr>
				<th data-options="field:'id',width:50">序号</th>
				<th data-options="field:'type',width:50">类型</th>
				<th data-options="field:'name',width:50">名称</th>
				<th data-options="field:'about',width:100">简介</th>
			</tr>
		</thead>
	</table>

最终效果如下,大功告成:

1人推荐
随时随地看视频
慕课网APP