目录
前言:
分页,是一种将所有数据分段展示给用户的技术.用户每次看到的不是全部数据,而是其中的一部分,如果在其中没有找到自习自己想要的内容,用户可以通过制定页码或是翻页的方式转换可见内容,直到找到自己想要的内容为止.其实这和我们阅读书籍很类似。
分页的意义:分页确实有效,但它一定会加大系统的复杂度,但可否不分页呢?如果数据量少的话当然可以.但是对于企业信息系统来说数据量不会限制在一个小范围内.如果不顾一切的Select * from某个表,再将返回的数据一古脑的扔给客户,即使客户能够忍受成千上万足够让人眼花缭乱的表格式数据,繁忙的网络,紧张的服务器也会提出它们无声的抗议,甚至有时会以彻底的罢工作为终结。
在我们实际开发中,会遇到这种场景,数据已经分页显示,此时客户会有这种需求,希望在这一页上进行条件搜索,根据自己搜索的条件来作为筛选。
由此可见,分页与搜索的联动至关重要,需要我们掌握。
一、项目搭建与项目结构
第一步首先是项目的ssm框架的搭建,其中包括依赖以及一些配置文件,这里我就不细讲了,不会的小伙伴可以看我这篇博客学习一下。
二、前端代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<style>
#td{
/*width: 70%;*/
background-color: aqua;
}
</style>
</head>
<body>
<center>
<h2>员工列表</h2>
</center>
</body>
<center>
<form action="${pageContext.request.contextPath}/emp/empList" method="post">
<input type="text" name="ename" placeholder="员工姓名" value="${requestScope.emp.ename}">
<input type="text" name="dname" placeholder="部门名称" value="${requestScope.emp.dname}">
<button>搜索</button>
</form>
<table cellspacing="0" border="1px" width="800px">
<tr>
<td>empno</td>
<td>ename</td>
<td>job</td>
<td>mgr</td>
<td>hiredate</td>
<td>sal</td>
<td>comm</td>
<td>deptno</td>
<td>dname</td>
<td>loc</td>
<td>grade</td>
<td>losal</td>
<td>hisal</td>
<td id="td">操作</td>
</tr>
<c:forEach items="${emps}" var="e">
<tr>
<td>${e.empno}</td>
<td>${e.ename}</td>
<td>${e.job}</td>
<td>${e.mgr}</td>
<td>${e.hiredate}</td>
<td>${e.sal}</td>
<td>${e.comm}</td>
<td>${e.deptno}</td>
<td>${e.dname}</td>
<td>${e.loc}</td>
<td>${e.grade}</td>
<td>${e.losal}</td>
<td>${e.hisal}</td>
<td><a href="${pageContext.request.contextPath}/updateBook.jsp?id=${b.id}&name=${b.name}&price=${b.price}&author=${b.author}&image=${b.image}&publishDate=${b.publishDate}">修改</a> <a href="${pageContext.request.contextPath}/book/delBook?id=${b.id}">删除</a></td>
</tr>
</c:forEach>
</table>
<c:if test="${requestScope.pageNum > 1}">
<a href="${pageContext.request.contextPath}/emp/empList?ename=${requestScope.emp.ename}&dname=${requestScope.emp.dname}">首页</a>
<a href="${pageContext.request.contextPath}/emp/empList?ename=${requestScope.emp.ename}&dname=${requestScope.emp.dname}&pageNum=${requestScope.pageNum-1}">上一页</a>
</c:if>
第${requestScope.pageNum}页
共${requestScope.pages}页
<c:if test="${requestScope.pageNum < requestScope.pages}">
<a href="${pageContext.request.contextPath}/emp/empList?ename=${requestScope.emp.ename}&dname=${requestScope.emp.dname}&pageNum=${requestScope.pageNum+1}">下一页</a>
<a href="${pageContext.request.contextPath}/emp/empList?ename=${requestScope.emp.ename}&dname=${requestScope.emp.dname}&pageNum=${requestScope.pages}">尾页</a>
</c:if>
</center>
</html>
这一界面主要实现从后台获取数据,显示列表并分页,还能通过form表单相应后台调用方法,实现搜索与分页联动。注意:记得外部导入jstl哦~
二、后端代码
1)controller层
package com.crm.controller;
import com.crm.entity.Emp;
import com.crm.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
@RequestMapping("/emp")
public class EmpController {
@Autowired
private EmpService empService;
@RequestMapping("/empList")
public String empList(Model model, @RequestParam(value = "pageNum",defaultValue = "1") int pageNum, @RequestParam(value = "pageSize",defaultValue = "2") int pageSize, Emp emp) {
int total = empService.empList(emp, 0, 0).size();
int pages = total % pageSize == 0?total / pageSize:total / pageSize + 1;
List<Emp> emps = empService.empList(emp, pageNum, pageSize);
model.addAttribute("emp",emp);
model.addAttribute("emps",emps);
model.addAttribute("pageNum",pageNum);
model.addAttribute("pages",pages);
return "index";
}
}
2)service层
(service接口)
package com.crm.service;
import com.crm.entity.Emp;
import java.util.List;
public interface EmpService {
List<Emp> empList(Emp emp,Integer pageNum,Integer pageSize);
}
(service实现类)
package com.crm.service.impl;
import com.crm.entity.Emp;
import com.crm.mapper.EmpMapper;
import com.crm.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public List<Emp> empList(Emp emp, Integer pageNum, Integer pageSize) {
return empMapper.empList(emp,(pageNum-1)*pageSize,pageSize);
}
}
3)持久层
package com.crm.mapper;
import com.crm.entity.Emp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Entity com.crm.entity.Emp
*/
public interface EmpMapper {
int deleteByPrimaryKey(Long id);
int insert(Emp record);
int insertSelective(Emp record);
Emp selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(Emp record);
int updateByPrimaryKey(Emp record);
/**
* 显示员工列表,搜索并分页
*/
List<Emp> empList(@Param("emp") Emp emp, @Param("index") Integer index, @Param("pageSize") Integer pageSize);
}
注意:这里的持久层mapper是idea插件mybatis-x根据数据库自动生成的,里面有对应的基本的简单的crud方法,但是没有自己需要的方法,所以需要我们自己重新写一个查询的接口方法。当自己定义的方法里面有几个参数时,需要添加一个@Param注解 取别名,这一点容易忽视,要特别注意。
4)持久层对应的xml文件(执行sql语句的地方)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.crm.mapper.EmpMapper">
<select id="empList" resultMap="empListMap">
select *,d.deptno dno from emp e join dept d on e.deptno = d.deptno
join salgrade s on e.sal between s.losal and s.hisal where 1=1
<if test="emp.ename != null and emp.ename != ''">
and e.ename like concat("%",#{emp.ename},"%")
</if>
<if test="emp.dname != null and emp.dname != ''">
and d.dname = #{emp.dname}
</if>
<if test="pageSize != null and pageSize != 0">
limit #{index},#{pageSize}
</if>
</select>
<resultMap id="empListMap" type="com.crm.entity.Emp" autoMapping="true">
<id column="empno" property="empno"/>
<association property="dept" javaType="com.crm.entity.Dept" autoMapping="true">
<id column="dno" property="deptno"/>
</association>
<association property="salgrade" javaType="com.crm.entity.Salgrade" autoMapping="true">
<id column="grade" property="grade"/>
</association>
</resultMap>
</mapper>
5)实体类
package com.crm.entity;
import java.io.Serializable;
import java.util.Date;
/**
*
* @TableName emp
*/
public class Emp implements Serializable {
/**
*
*/
private Integer empno;
/**
*
*/
private String ename;
/**
*
*/
private String job;
/**
*
*/
private Integer mgr;
/**
*
*/
private Date hiredate;
/**
*
*/
private Double sal;
/**
*
*/
private Double comm;
/**
*
*/
private Integer deptno;
private Dept dept;
private Salgrade salgrade;
private String dname;
private String loc;
private Integer grade;
private Integer losal;
private Integer hisal;
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
public Integer getLosal() {
return losal;
}
public void setLosal(Integer losal) {
this.losal = losal;
}
public Integer getHisal() {
return hisal;
}
public void setHisal(Integer hisal) {
this.hisal = hisal;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public Salgrade getSalgrade() {
return salgrade;
}
public void setSalgrade(Salgrade salgrade) {
this.salgrade = salgrade;
}
private static final long serialVersionUID = 1L;
/**
*
*/
public Integer getEmpno() {
return empno;
}
/**
*
*/
public void setEmpno(Integer empno) {
this.empno = empno;
}
/**
*
*/
public String getEname() {
return ename;
}
/**
*
*/
public void setEname(String ename) {
this.ename = ename;
}
/**
*
*/
public String getJob() {
return job;
}
/**
*
*/
public void setJob(String job) {
this.job = job;
}
/**
*
*/
public Integer getMgr() {
return mgr;
}
/**
*
*/
public void setMgr(Integer mgr) {
this.mgr = mgr;
}
/**
*
*/
public Date getHiredate() {
return hiredate;
}
/**
*
*/
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
/**
*
*/
public Double getSal() {
return sal;
}
/**
*
*/
public void setSal(Double sal) {
this.sal = sal;
}
/**
*
*/
public Double getComm() {
return comm;
}
/**
*
*/
public void setComm(Double comm) {
this.comm = comm;
}
/**
*
*/
public Integer getDeptno() {
return deptno;
}
/**
*
*/
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", mgr=" + mgr +
", hiredate=" + hiredate +
", sal=" + sal +
", comm=" + comm +
", deptno=" + deptno +
", dept=" + dept +
", salgrade=" + salgrade +
'}';
}
}
注意:我这儿是三表查询,通过员工表查询到员工信息、部门信息和薪资信息,所以要在此实体类中添加部门类和薪资类的对象,因为在前端界面还会显示其他表字段的信息,所以还需要在此实体类中添加所需其他表字段的属性,最后,一定要记得提供新加属性字段的get/set方法。
此图是我在此实体类中新加的字段属性:
三、运行结果
可以根据员工姓名模糊查询,根据部门名称精准查询。