page
情景引入:
小白:起床起床,,,快起床!!!
我:怎么怎么了,小白你到底又怎么了。。
小白:我发现在Web系统中,分页是一种很常见的功能,可是,我之前写的方法都比较麻烦,移植性不是很高,有没有什么好办法可以快速实现分页的呢?
我:确实是的,分页功能几乎在每个系统中都是存在的,它的实现也是有很多种方式的。
小白:对呀,有没有什么好方法呢?
我:这个嘛,对于分页来说的话,其实我们在复杂的系统中,有很多特别的处理,这些都是需要我们进行自定义的编写处理的。但是,如果你就想实现一种分页效果的话,我可以给你提提建议。
小白:好哟,赶紧说赶紧说!!
我:害我又没有懒觉睡,真是的。那接下来,我跟你说说用一种分页插件如何进行快速实现分页效果吧。
情景分析:
我们在任何的系统中,分页功能是必不可少的。然而,对于这个功能如果有一种快速开发的实现方式,当然可以节省我们很多的时间了。接下来,我就给大家基于不同的环境来说说如何使用一个分页插件:pagehelper。。不过,大家可要记住了,对于不同的情况,都要认真分析场景,而不是只会套用哦。。当然,如果你想用最原始的方式实现,也是可以的,我也写了两种方法,会在讲解完后,贴到后面,如果有需要的就进行稍微查看即可(但是,不是非常理想,仅供参考)。
情景一:(SpringBoot 和 MyBATis环境)
方法一:使用pagehelper-spring-boot-starter的形式(最简单和通用的方式)
使用步骤:
(1)在pom.xml文件中引入依赖库
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
(2)在APPlication.properties中添加分页配置
# 配置pageHelper分页插件的内容
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
或者在application.yml文件中添加分页配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
(3)进行使用。(可以在controller层或者service层使用即可)
/**
* 查询所有的person内容
* @return
*/
@requestMapping(value = "/list")
public String jumpJsp(Map<String, Object> result){
PageHelper.startPage(3 , 3);
List<Person> personList = personService.findPerson();
//得到分页的结果对象
PageInfo<Person> personPageInfo = new PageInfo<>(personList);
//得到分页中的person条目对象
List<Person> pageList = personPageInfo.getList();
//将结果存入map进行传送
result.put("pageInfo" , pageList);
return "person_list";
}
解析:
(1)PageHelper.startPage(pageNum , pageSize),这个方法就是类似我们数据库操作的limit start , count
(2)得到的对象PageInfo里面包含很多的字段信息,这个可以自己看源码,非常详细
(3)如果我们只想得到分页处理之后我们的实体对象的结果,那么就调用PageInfo对象的getList()方法即可。
(4)这种配置使用的方式是最通用的方式,也就是对于环境搭建不同方式都可以利用这种使用方法。
问题:如果运行时出现,org.springframework.beans.factory.BeanCreationException: ERROR creating bean with name 'com.github.pagehelper.autoconfigure.PageHelperAutoconfiguration': 这个错误。
解决办法:这是由于分页插件pagehelper的版本和mybatis不兼容的原因,修改分页插件的版本即可。
方法二:使用最原始的形式(SpringBoot+Mybatis配置文件的形式,也就是整合环境还是利用xml的形式搭建的,但是都是通过@configuration注解开发类)
使用步骤:
(1)在pom.xml文件中,添加分页插件的依赖(注意和第一种方法的区别)
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
(2)在mybatis的配置文件中添加如下的插件
<!-- 配置mybatis的分页插件PageHelper -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 设置数据库类型oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库 -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
(3)在controller或者service层进行使用插件
/**
* 查询所有的person内容
* @return
*/
@RequestMapping(value = "/list")
public String jumpJsp(Map<String, Object> result){
PageHelper.startPage(1 , 5);
List<Person> personList = personService.findPerson();
//得到分页的结果对象
PageInfo<Person> personPageInfo = new PageInfo<>(personList);
//得到分页中的person条目对象
List<Person> pageList = personPageInfo.getList();
//将结果存入map进行传送
result.put("pageInfo" , pageList);
return "person_list";
}
分析:对于这种方法的话,适用于对整合环境还是通过mybatis.xml的形式,所以,这种是具有针对性的一种情况。方法三:使用最原始的方式(SpringBoot+Mybatis搭建中,Mybatis是利用在application.properties进行设置,并且mapper文件的操作还是使用.xml形式编写的sql语句,而非mapper注解编写)
使用步骤:
(1)在pom.xml文件中添加分页插件的依赖
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
(2)添加下面一个类
package com.hnu.scw.config;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlsessionfactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @ Author :scw
* @ Date :Created in 下午 2:48 2018/6/17 0017
* @ Description:用于配置分页插件的使用
* @ Modified By:
* @Version: $version$
*/
@Configuration
public class PgeHeplerConfig {
//将分页插件注入到容器中
@Bean
public PageHelper pageHelper() {
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
//添加插件
new SqlSessionFactoryBean().setPlugins(new Interceptor[]{pageHelper});
return pageHelper;
}
}
或者如下的代码:
package com.hnu.scw.config;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @ Author :scw
* @ Date :Created in 下午 2:48 2018/6/17 0017
* @ Description:用于配置分页插件的使用
* @ Modified By:
* @Version: $version$
*/
@Configuration
public class PgeHeplerConfig {
//将分页插件注入到容器中
@Bean
public PageHelper pageHelper() {
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("helperDialect", "mysql");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
return pageHelper;
}
}
还可以直接在springboot的启动类添加下面的代码即可。(其实都一样的道理,因为上面的类都是用了@Configuration注解配置了的,也就是添加到了容器中)
//将分页插件注入到容器中
@Bean
public PageHelper pageHelper() {
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("helperDialect", "mysql");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
return pageHelper;
}
(3)直接使用
/**
* 查询所有的person内容
* @return
*/
@RequestMapping(value = "/list")
public String jumpJsp(Map<String, Object> result){
PageHelper.startPage(1 , 5);
List<Person> personList = personService.findPerson();
//得到分页的结果对象
PageInfo<Person> personPageInfo = new PageInfo<>(personList);
//得到分页中的person条目对象
List<Person> pageList = personPageInfo.getList();
//将结果存入map进行传送
result.put("pageInfo" , pageList);
return "person_list";
}
情景二:Spring+SpringMVC+Mybatis+Maven环境
使用步骤:(其实这个就类似情景一种的方式二,换汤不换药)
(1)在pom.xml中添加分页插件的依赖
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
(2)在mybatis中的配置文件SqlMapConfig.xml(这个名字是你自己搭建环境所取的,就是配置一些关于Mybatis的配置文件)添加分页插件。
<!-- 配置mybatis的分页插件PageHelper -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 设置数据库类型Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库 -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
(3)在controller层或者service实现层中使用分页。
/**
* 查询所有的person内容
* @return
*/
@RequestMapping(value = "/list")
public String jumpJsp(Map<String, Object> result){
PageHelper.startPage(1 , 8);
List<Person> personList = personService.findPerson();
//得到分页的结果对象
PageInfo<Person> personPageInfo = new PageInfo<>(personList);
//得到分页中的person条目对象
List<Person> pageList = personPageInfo.getList();
//将结果存入map进行传送
result.put("pageInfo" , pageList);
return "person_list";
}
总结:
(1)pagehelper插件本身就是基于Mybatis这种框架进行开发的插件。所以,主要都是针对Mybatis数据操作的架构的。
(2)上面描述了多种情况的具体配置方式,都是自身经过实际开发编写的,而且对于不同的情景,各位要理解为什么要这样,这虽然只是讲解了分页插件的使用,当遇到其他插件的时候,都可以类似进行处理。
(3)如果是用到的SSH(Spring+SpringMVC+Hibernate)或者SpringBoot+Hibernate这样的架构的时候,这个插件是无法使用的,就需要自己通过hibernate的形式进行处理,比如可以用HQL语法或者Criteria进行处理即可。毕竟,Hibernate是一种全自动化的数据库操作框架。
下面的内容,是关于原始方式实现分页效果,仅供各位进行参考(其中是通过实例来帮助大家进行分析)
实现方法一:通过自定义分页标签(JSP)
分页,这个功能,我想在很多的系统中,都有用到过吧。这已经是非常非常普通的应用功能了,所以就需要将这个功能能自定义为一个jsp标签的话,那就肯定很方便了。所以下面就说一下,如果实现这个功能。
步骤:
(1)写两个Java类,其中Page,很简单就是一个分页对象,然后navigationTag这个就是自定义标签的核心映射类了(如果对于这个自定义标签的流程不是很清楚的话,可以看看我之前写的J2EE的知识点中的内容,都很详细介绍了)。
Page:
package com.hnuscw.common.utils;
import java.util.List;
public class Page<T> {
private int total;
private int page;
private int size;
private List<T> rows;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
}
Navigation:
package com.hnuscw.common.utils;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.taglibs.standard.tag.common.core.UrlSupport;
/**
* 显示格式 上一页 1 2 3 4 5 下一页
*/
public class NavigationTag extends TagSupport {
static final long serialversionuid = 2372405317744358833L;
/**
* request 中用于保存Page<E> 对象的变量名,默认为“page”
*/
private String bean = "page";
/**
* 分页跳转的url地址,此属性必须
*/
private String url = null;
/**
* 显示页码数量
*/
private int number = 5;
@Override
public int doStartTag() throws JspException {
JspWriter writer = pageContext.getOut();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
Page page = (Page)request.getAttribute(bean);
if (page == null)
return SKIP_BODY;
url = resolveUrl(url, pageContext);
try {
//计算总页数
int pageCount = page.getTotal() / page.getSize();
if (page.getTotal() % page.getSize() > 0) {
pageCount++;
}
writer.print("<nav><ul class=\"pagination\">");
//显示“上一页”按钮
if (page.getPage() > 1) {
String preUrl = append(url, "page", page.getPage() - 1);
preUrl = append(preUrl, "rows", page.getSize());
writer.print("<li><a href=\"" + preUrl + "\">上一页</a></li>");
} else {
writer.print("<li class=\"disabled\"><a href=\"#\">上一页</a></li>");
}
//显示当前页码的前2页码和后两页码
//若1 则 1 2 3 4 5, 若2 则 1 2 3 4 5, 若3 则1 2 3 4 5,
//若4 则 2 3 4 5 6 ,若10 则 8 9 10 11 12
int indexPage = (page.getPage() - 2 > 0)? page.getPage() - 2 : 1;
for(int i=1; i <= number && indexPage <= pageCount; indexPage++, i++) {
if(indexPage == page.getPage()) {
writer.print( "<li class=\"active\"><a href=\"#\">"+indexPage+"<span class=\"sr-only\">(current)</span></a></li>");
continue;
}
String pageUrl = append(url, "page", indexPage);
pageUrl = append(pageUrl, "rows", page.getSize());
writer.print("<li><a href=\"" + pageUrl + "\">"+ indexPage +"</a></li>");
}
//显示“下一页”按钮
if (page.getPage() < pageCount) {
String nextUrl = append(url, "page", page.getPage() + 1);
nextUrl = append(nextUrl, "rows", page.getSize());
writer.print("<li><a href=\"" + nextUrl + "\">下一页</a></li>");
} else {
writer.print("<li class=\"disabled\"><a href=\"#\">下一页</a></li>");
}
writer.print("</nav>");
} catch (IOException e) {
e.printstacktrace();
}
return SKIP_BODY;
}
private String append(String url, String key, int value) {
return append(url, key, String.valueOf(value));
}
/**
* 为url 参加参数对儿
*
* @param url
* @param key
* @param value
* @return
*/
private String append(String url, String key, String value) {
if (url == null || url.trim().length() == 0) {
return "";
}
if (url.indexof("?") == -1) {
url = url + "?" + key + "=" + value;
} else {
if(url.endsWith("?")) {
url = url + key + "=" + value;
} else {
url = url + "&" + key + "=" + value;
}
}
return url;
}
/**
* 为url 添加翻页请求参数
*
* @param url
* @param pageContext
* @return
* @throws javax.servlet.jsp.JspException
*/
private String resolveUrl(String url, javax.servlet.jsp.PageContext pageContext) throws JspException{
//UrlSupport.resolveUrl(url, context, pageContext)
Map params = pageContext.getRequest().getparameterMap();
for (Object key:params.keySet()) {
if ("page".equals(key) || "rows".equals(key)) continue;
Object value = params.get(key);
if (value == null) continue;
if (value.getClass().isArray()) {
url = append(url, key.toString(), ((String[])value)[0]);
} else if (value instanceof String) {
url = append(url, key.toString(), value.toString());
}
}
return url;
}
/**
* @return the bean
*/
public String getBean() {
return bean;
}
/**
* @param bean the bean to set
*/
public void setBean(String bean) {
this.bean = bean;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}
public void setNumber(int number) {
this.number = number;
}
}
(2)编写自定义标签的tld,命令为commons.tld,并且放在WEB-INF下面的tld文件下(这个文件自己创建就是了)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>2.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>common</short-name>
<uri>http://hnuscw.com/common/</uri>
<display-name>Common Tag</display-name>
<description>Common Tag library</description>
<tag>
<name>page</name>
<tag-class>com.hnuscw.common.utils.NavigationTag</tag-class>
<body-content>JSP</body-content>
<description>create navigation for paging</description>
<attribute>
<name>bean</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>number</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
(3)在jsp页面中进行使用
引入标签:
<%@ taglib prefix="hnuscw" uri="http://hnuscw.com/common/"%>
使用标签:<p class="col-md-12 text-right">
<hnuscw:page url="${pageContext.request.contextpath }/customer/list.action" />
</p>
测试实例:为了方便很多的使用,我这就还是用一个实际的例子还显示这个效果吧。
jsp页面:命名为:customer.jsp(当然可以不要这么多内容,自行更改即可,只是这个就相当于一个管理系统的了,所以以后只需要稍微修改就可以)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="itcast" uri="http://itcast.cn/common/"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>客户列表-BootCRM</title>
<!-- Bootstrap Core CSS -->
<link href="<%=basePath%>css/bootstrap.min.css" rel="stylesheet">
<!-- MetisMenu CSS -->
<link href="<%=basePath%>css/metisMenu.min.css" rel="stylesheet">
<!-- DataTables CSS -->
<link href="<%=basePath%>css/dataTables.bootstrap.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="<%=basePath%>css/sb-admin-2.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="<%=basePath%>css/font-awesome.min.css" rel="stylesheet"
type="text/css">
<link href="<%=basePath%>css/boot-crm.css" rel="stylesheet"
type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<p id="wrapper">
<!-- Navigation -->
<nav class="navbar navbar-default navbar-static-top" role="navigation"
style="margin-bottom: 0">
<p class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span> <span class="icon-bar"></span> <span
class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">BOOT客户管理系统 v2.0</a>
</p>
<!-- /.navbar-header -->
<ul class="nav navbar-top-links navbar-right">
<li class="dropdown"><a class="dropdown-toggle"
data-toggle="dropdown" href="#"> <i class="fa fa-envelope fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-messages">
<li><a href="#">
<p>
<strong>令狐冲</strong> <span class="pull-right text-muted">
<em>昨天</em>
</span>
</p>
<p>今天晚上向大哥找我吃饭,讨论一下去梅庄的事...</p>
</a></li>
<li class="pider"></li>
<li><a class="text-center" href="#"> <strong>查看全部消息</strong>
<i class="fa fa-angle-right"></i>
</a></li>
</ul> <!-- /.dropdown-messages --></li>
<!-- /.dropdown -->
<li class="dropdown"><a class="dropdown-toggle"
data-toggle="dropdown" href="#"> <i class="fa fa-tasks fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-tasks">
<li><a href="#">
<p>
<p>
<strong>任务 1</strong> <span class="pull-right text-muted">完成40%</span>
</p>
<p class="progress progress-striped active">
<p class="progress-bar progress-bar-success"
role="progressbar" aria-valuenow="40" aria-valuemin="0"
aria-valuemax="100" style="width: 40%">
<span class="sr-only">完成40%</span>
</p>
</p>
</p>
</a></li>
<li class="pider"></li>
<li><a href="#">
<p>
<p>
<strong>任务 2</strong> <span class="pull-right text-muted">完成20%</span>
</p>
<p class="progress progress-striped active">
<p class="progress-bar progress-bar-info" role="progressbar"
aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"
style="width: 20%">
<span class="sr-only">完成20%</span>
</p>
</p>
</p>
</a></li>
<li class="pider"></li>
<li><a class="text-center" href="#"> <strong>查看所有任务</strong>
<i class="fa fa-angle-right"></i>
</a></li>
</ul> <!-- /.dropdown-tasks --></li>
<!-- /.dropdown -->
<li class="dropdown"><a class="dropdown-toggle"
data-toggle="dropdown" href="#"> <i class="fa fa-bell fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-alerts">
<li><a href="#">
<p>
<i class="fa fa-comment fa-fw"></i> 新回复 <span
class="pull-right text-muted small">4分钟之前</span>
</p>
</a></li>
<li class="pider"></li>
<li><a href="#">
<p>
<i class="fa fa-envelope fa-fw"></i> 新消息 <span
class="pull-right text-muted small">4分钟之前</span>
</p>
</a></li>
<li class="pider"></li>
<li><a href="#">
<p>
<i class="fa fa-tasks fa-fw"></i> 新任务 <span
class="pull-right text-muted small">4分钟之前</span>
</p>
</a></li>
<li class="pider"></li>
<li><a href="#">
<p>
<i class="fa fa-upload fa-fw"></i> 服务器重启 <span
class="pull-right text-muted small">4分钟之前</span>
</p>
</a></li>
<li class="pider"></li>
<li><a class="text-center" href="#"> <strong>查看所有提醒</strong>
<i class="fa fa-angle-right"></i>
</a></li>
</ul> <!-- /.dropdown-alerts --></li>
<!-- /.dropdown -->
<li class="dropdown"><a class="dropdown-toggle"
data-toggle="dropdown" href="#"> <i class="fa fa-user fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#"><i class="fa fa-user fa-fw"></i> 用户设置</a></li>
<li><a href="#"><i class="fa fa-gear fa-fw"></i> 系统设置</a></li>
<li class="pider"></li>
<li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i>
退出登录</a></li>
</ul> <!-- /.dropdown-user --></li>
<!-- /.dropdown -->
</ul>
<!-- /.navbar-top-links -->
<p class="navbar-default sidebar" role="navigation">
<p class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li class="sidebar-search">
<p class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="查询内容...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search" style="padding: 3px 0 3px 0;"></i>
</button>
</span>
</p> <!-- /input-group -->
</li>
<li><a href="customer.action" class="active"><i
class="fa fa-edit fa-fw"></i> 客户管理</a></li>
<li><a href="salevisit.action"><i
class="fa fa-dashboard fa-fw"></i> 客户拜访</a></li>
</ul>
</p>
<!-- /.sidebar-collapse -->
</p>
<!-- /.navbar-static-side --> </nav>
<p id="page-wrapper">
<p class="row">
<p class="col-lg-12">
<h1 class="page-header">客户管理</h1>
</p>
<!-- /.col-lg-12 -->
</p>
<!-- /.row -->
<p class="panel panel-default">
<p class="panel-body">
<form class="form-inline" action="${pageContext.request.contextPath }/customer/list.action" method="get">
<p class="form-group">
<label for="customerName">客户名称</label>
<input type="text" class="form-control" id="customerName" value="${custName }" name="custName">
</p>
<p class="form-group">
<label for="customerFrom">客户来源</label>
<select class="form-control" id="customerFrom" placeholder="客户来源" name="custSource">
<option value="">--请选择--</option>
<c:foreach items="${fromType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custSource}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
<p class="form-group">
<label for="custIndustry">所属行业</label>
<select class="form-control" id="custIndustry" name="custIndustry">
<option value="">--请选择--</option>
<c:forEach items="${industryType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custIndustry}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
<p class="form-group">
<label for="custLevel">客户级别</label>
<select class="form-control" id="custLevel" name="custLevel">
<option value="">--请选择--</option>
<c:forEach items="${levelType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custLevel}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
<button type="submit" class="btn btn-primary">查询</button>
</form>
</p>
</p>
<p class="row">
<p class="col-lg-12">
<p class="panel panel-default">
<p class="panel-heading">客户信息列表</p>
<!-- /.panel-heading -->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>客户名称</th>
<th>客户来源</th>
<th>客户所属行业</th>
<th>客户级别</th>
<th>固定电话</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${page.rows}" var="row">
<tr>
<td>${row.cust_id}</td>
<td>${row.cust_name}</td>
<td>${row.cust_source}</td>
<td>${row.cust_industry}</td>
<td>${row.cust_level}</td>
<td>${row.cust_phone}</td>
<td>${row.cust_mobile}</td>
<td>
<a href="#" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#customerEditDialog" class="btn btn-danger btn-xs" />
</p>
<!-- /.panel-body -->
</p>
<!-- /.panel -->
</p>
<!-- /.col-lg-12 -->
</p>
</p>
<!-- /#page-wrapper -->
</p>
<!-- 客户编辑对话框 -->
<p class="modal fade" id="customerEditDialog" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<p class="modal-dialog" role="document">
<p class="modal-content">
<p class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">修改客户信息</h4>
</p>
<p class="modal-body">
<form class="form-horizontal" id="edit_customer_form">
<input type="hidden" id="edit_cust_id" name="cust_id"/>
<p class="form-group">
<label for="edit_customerName" class="col-sm-2 control-label">客户名称</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_customerName" placeholder="客户名称" name="cust_name">
</p>
</p>
<p class="form-group">
<label for="edit_customerFrom" style="float:left;padding:7px 15px 0 27px;">客户来源</label>
<p class="col-sm-10">
<select class="form-control" id="edit_customerFrom" placeholder="客户来源" name="cust_source">
<option value="">--请选择--</option>
<c:forEach items="${fromType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custSource}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
</p>
<p class="form-group">
<label for="edit_custIndustry" style="float:left;padding:7px 15px 0 27px;">所属行业</label>
<p class="col-sm-10">
<select class="form-control" id="edit_custIndustry" name="cust_industry">
<option value="">--请选择--</option>
<c:forEach items="${industryType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custIndustry}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
</p>
<p class="form-group">
<label for="edit_custLevel" style="float:left;padding:7px 15px 0 27px;">客户级别</label>
<p class="col-sm-10">
<select class="form-control" id="edit_custLevel" name="cust_level">
<option value="">--请选择--</option>
<c:forEach items="${levelType}" var="item">
<option value="${item.dict_id}"<c:if test="${item.dict_id == custLevel}"> selected</c:if>>${item.dict_item_name }</option>
</c:forEach>
</select>
</p>
</p>
<p class="form-group">
<label for="edit_linkMan" class="col-sm-2 control-label">联系人</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_linkMan" placeholder="联系人" name="cust_linkman">
</p>
</p>
<p class="form-group">
<label for="edit_phone" class="col-sm-2 control-label">固定电话</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_phone" placeholder="固定电话" name="cust_phone">
</p>
</p>
<p class="form-group">
<label for="edit_mobile" class="col-sm-2 control-label">移动电话</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_mobile" placeholder="移动电话" name="cust_mobile">
</p>
</p>
<p class="form-group">
<label for="edit_zipcode" class="col-sm-2 control-label">邮政编码</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_zipcode" placeholder="邮政编码" name="cust_zipcode">
</p>
</p>
<p class="form-group">
<label for="edit_address" class="col-sm-2 control-label">联系地址</label>
<p class="col-sm-10">
<input type="text" class="form-control" id="edit_address" placeholder="联系地址" name="cust_address">
</p>
</p>
</form>
</p>
<p class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.crm.mapper.basedictDao">
<!-- 查询 -->
<select id="selectBaseDictListByCode" parameterType="String" resultType="BaseDict">
select * from base_dict where dict_type_code = #{value}
</select>
</mapper>
分页处理的映射mapper:
<?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.itheima.crm.mapper.CustomerDao">
<!-- //总条数 -->
<!-- public integer customerCountByQueryVo(QueryVo vo); private String custName;
private String custSource; private String custIndustry; private String custLevel; -->
<select id="customerCountByQueryVo" parameterType="QueryVo"
resultType="Integer">
select count(1) from customer
<where>
<if test="custName != null and custName != ''">
cust_name like "%"#{custName}"%"
</if>
<if test="custSource != null and custSource != ''">
and cust_source = #{custSource}
</if>
<if test="custIndustry != null and custIndustry != ''">
and cust_industry = #{custIndustry}
</if>
<if test="custLevel != null and custLevel != ''">
and cust_level = #{custLevel}
</if>
</where>
</select>
<!-- //结果集 -->
<!-- public List<Customer> selectCustomerListByQueryVo(QueryVo vo); -->
<select id="selectCustomerListByQueryVo" parameterType="QueryVo"
resultType="Customer">
select * from customer
<where>
<if test="custName != null and custName != ''">
cust_name like "%"#{custName}"%"
</if>
<if test="custSource != null and custSource != ''">
and cust_source = #{custSource}
</if>
<if test="custIndustry != null and custIndustry != ''">
and cust_industry = #{custIndustry}
</if>
<if test="custLevel != null and custLevel != ''">
and cust_level = #{custLevel}
</if>
</where>
limit #{startRow},#{size}
</select>
</mapper>
PS:(1)上面的代码加上对自定义标签的使用的话,就实现了分页内容的处理了,所以,如果需要使用的话就可以根据这样的内容进行处理即可。此外,上面的jsp中是有条件搜索的,所以代码中也加入了对条件搜索的处理,如果你那界面只是想实现分页处理的话,那么在每个层次中将条件处理的代码删除即可,这样也不会进行影响,关键还是要看懂代码,如果看懂了的话,还是很好进行处理的。当然,这并不是最优化的情况,还能够进行处理,只是这是一种方法而已。
(2)如果要使用上面的jsp代码的话, 要先配置一下下面的内容,对内容进行放行处理.
实现方法二:通过JSP控制分页处理的方法
分析:在第二点中提到了分页的方法,主要是利用jstl中的自定义标签来实现的,接下来的话,介绍一下另外一种方法,就是如何利用jsp页面来控制分页的处理方法。
步骤:(1)编写jsp中的分页内容代码(这里主要就是写一下分页的页面界面和当页数过多的时候如何进行处理的问题)
<!-- 分页内容的处理部分 -->
<td style="vertical-align:top;">
<p class="pagination" style="float: right;padding-top: 0px;margin-top: 0px;">
<ul>
<li><a>共<font color=red>${page.totalResult}</font>条</a></li>
<li><input type="number" value="" id="jumpPageNumber" style="width:50px;text-align:center;float:left" placeholder="页码"/></li>
<li style="cursor:pointer;"><a class="btn btn-Mini btn-success">跳转</a></li>
<c:choose>
<c:when test="${page.currentPage == 1 }">
<li><a>首页</a></li>
<li><a>上页</a></li>
<!-- 分是否为第一页的两种情况,不为第一页的话,那么就要设置首页和上一页为有onclick点击事件 -->
</c:when>
<c:otherwise>
<li style="cursor:pointer;"><a begin="${page.totalPage-4}" end="${page.totalPage}" step="1">
<c:if test="${index1 >= 1}">
<c:choose>
<c:when test="${page.currentPage == index1}">
<li><a><b style="color: red;">${page.currentPage}</b></a></li>
</c:when>
<c:otherwise>
<li style="cursor:pointer;"><a begin="1" end="${page.totalPage}">
<!-- 判断页码是否是当前页,是的话,就换个颜色来标记 -->
<c:choose>
<c:when test="${page.currentPage == pagenumber}">
<li><a><b style="color: red;">${page.currentPage}</b></a></li>
</c:when>
<c:otherwise>
<li style="cursor:pointer;"><a begin="${page.currentPage-1}" end="${page.currentPage+3}"> <!-- 从当前页面减一的页面数开始,这样点击前面一页就会显示其他的页面,从而实现页面跳转 -->
<c:choose>
<c:when test="${page.currentPage == index2}">
<li><a><b style="color: red;">${page.currentPage}</b></a></li>
</c:when>
<c:otherwise>
<li style="cursor:pointer;"><a begin="1" end="5">
<c:choose>
<c:when test="${page.currentPage == index3}">
<li><a><b style="color: red;">${page.currentPage}</b></a></li>
</c:when>
<c:otherwise>
<li style="cursor:pointer;"><a onchange="changeCount(this.value)">
<option value="${page.showCount}">${page.showCount}</option>
<option value='5'>5</option>
<option value='10'>10</option>
<option value='20'>20</option>
<option value='30'>30</option>
<option value='40'>40</option>
<option value='50'>50</option>
<option value='60'>60</option>
<option value='70'>70</option>
</select>
</li>
</ul>
</p>
</td>
备注:1:上面是放在一个table标签中的,所以是用td标签来进行标识2:这里默认的处理是每一个分页是分5页内容,如果需要进行变化的话,那么自己进行修改相对应的注释中的内容即可
(2)jsp中的JS代码(用于控制点击页面的跳转处理)
//下面都是分页处理的操作
//(1)操作1:点击页码进行显示数据
function changePage(clickpage){
//注意点:
//(1)这里用ajax进行处理的话会存在问题,因为ajax无法进行页面跳转,所以如果用ajax的话,那么就要回到这个success中进行拼接内容,感觉有点麻烦了。
//(2)获取搜索框中是否有内容
var retrieve_content = $('#retrieve_content').val();
//(3)直接重定向带参数过去,currentPage表示将要显示的页面,showCount表示为每页的数据条数
window.location = "${pageContext.request.contextPath}/asset/asystem_showapprover?currentPage="+clickpage+"&showCount="+${page.showCount}+"&retrieve_content="+ encodeURI(encodeURI(retrieve_content));
/* $.ajax({
url:'${pageContext.request.contextPath}/asset/asystem_showapprover',
data:{"currentPage":clickpage},
async:true,
type:"POST",
success:function(data){
},
error:function(){
alert("切换失败!请稍后重试!");
},
dataType:"json"
}); */
}
//操作2:点击上下页,进行页码内容的改变
function nextPage(clickpage){
//(1)获取搜索框中是否有内容
var retrieve_content = $('#retrieve_content').val(); //后面要注意编码,因为如果是中文的话,这样传会发生乱码的,那么搜索肯定就匹配不到内容
window.location = "${pageContext.request.contextPath}/asset/asystem_showapprover?currentPage="+clickpage+"&showCount="+${page.showCount}+"&retrieve_content="+ encodeURI(encodeURI(retrieve_content));
}
//操作3:选择下拉框的时候,进行页面大小的改变
function changeCount(pagesize){
//(1)获取搜索框中是否有内容
var retrieve_content = $('#retrieve_content').val(); //后面要注意编码,因为如果是中文的话,这样传会发生乱码的,那么搜索肯定就匹配不到内容
window.location = "${pageContext.request.contextPath}/asset/asystem_showapprover?currentPage="+${page.currentPage}+"&showCount="+pagesize+"&retrieve_content="+ encodeURI(encodeURI(retrieve_content));
}
//操作4:处理跳转按钮页面的处理
function jumpPage(){
//1.获取页码框中的数值大小
var toPaggeVlue = $('#jumpPageNumber').val();
//2.对数值进行一些判断,是否符合正常的规范
if(toPaggeVlue == ''){ //如果是空,就设置为1
$('#jumpPageNumber').val(1);
toPaggeVlue =1;
}
if(isNaN(Number(toPaggeVlue))){ //如果是非数字,也就设置为1,其实这个在input组件中,已经可以控制了
$('#jumpPageNumber').val(1);
toPaggeVlue =1;
}
//3:执行nextPage函数就可以了
nextPage(toPaggeVlue);
}
备注:这里就是简单的JS跳转控制的代码了
(3)PgaeOption自定义分页处理的对象(主要就是用于管理分页的内容)
package com.mbfw.entity.assets;
import com.mbfw.util.PageData;
public class PageOption {
private int showCount; // 每页显示记录数
private int totalPage; // 总页数
private int totalResult; // 总记录数
private int currentPage; // 当前页
private int currentResult; // 当前记录起始索引
private PageData pd ; //封装一个PageData对象,主要是为了能够方便进行检索功能
public PageData getPd() {
return pd;
}
public void setPd(PageData pd) {
this.pd = pd;
}
public PageOption(int showCount , int currentPage){
this.showCount = showCount;
this.currentPage = currentPage;
}
public int getShowCount() {
return showCount;
}
public void setShowCount(int showCount) {
this.showCount = showCount;
}
public int getTotalPage() {
if (totalResult % showCount == 0)
totalPage = totalResult / showCount;
else
totalPage = totalResult / showCount + 1;
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getTotalResult() {
return totalResult;
}
public void setTotalResult(int totalResult) {
this.totalResult = totalResult;
}
public int getCurrentPage() {
if (currentPage <= 0)
currentPage = 1;
if (currentPage > getTotalPage())
currentPage = getTotalPage();
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
//获取当前页的数据条的索引
public int getCurrentResult() {
currentResult = (getCurrentPage() - 1) * getShowCount();
if (currentResult < 0)
currentResult = 0;
return currentResult;
}
public void setCurrentResult(int currentResult) {
this.currentResult = currentResult;
}
}
备注:其中做了一些页面数目的控制的管理,大家应该一看就能够明白含义的。当然,这些控制在controller层或者service层进行管理都可以的哦!!!
(4)controller层代码
@Autowired
private AssetApproverManageService ams;
//点击审核人员,进行显示所有审核人员信息
@RequestMapping(value="/asystem_showapprover")
public modelandview showApproverInfo() throws Exception{
ModelAndView mav = this.getModelAndView();
PageData pd = this.getPageData();
List<PageData> listApprover = new ArrayList<PageData>();
PageOption page = new PageOption(5, 1); //默认初始化一进来显示就是每页显示5条,当前页面为1
//(1)获取是否有传过来需要显示的页面数,如果有,就设置相应的属性
if(pd.getString("currentPage") != null){
page.setCurrentPage(Integer.parseInt(pd.getString("currentPage")));
}
//(2)获取是否有传过来每个页面显示的条数,如果有,就设置相应的属性
if(pd.getString("showCount") != null){
page.setShowCount(Integer.parseInt(pd.getString("showCount")));
}
//------没有进行检索的处理-----
if(pd.getString("retrieve_content") == null || pd.getString("retrieve_content") == ""){
//(3)查询数据库中数据的总条数
Integer totalnumber = ams.findTotalDataNumber();
//(4)设置总的数据条数
page.setTotalResult(totalnumber);
//(5)设置需要显示的数据的索引,其实这有个公式就是为了分页查询limit (currentPage-1)*showcount,showcount即可
page.setCurrentResult((page.getCurrentPage()-1)*(page.getShowCount()));
//(6)查询数据库,返回对应条数的数据
listApprover = ams.listPdPageApprover(page);
}
//--------进行检索处理
else{
//(3)获取传送过来的进行检索的内容(这里要解码,因为如果是中文的话就会发生乱码问题)
pd.put("retrieve_content", URLDecoder.decode(pd.getString("retrieve_content"), "utf-8"));
//(4)设置分页中需要进行检索的姓名的内容,便于在分页中根据姓名获取内容
page.setPd(pd);
//(5)查询对应审核人员姓名的数据总条数
Integer totalnumber = ams.findNumberBySearchName(page);
//(6)设置总的数据条数
page.setTotalResult(totalnumber);
//(7)设置需要显示的数据的索引
page.setCurrentResult((page.getCurrentPage()-1)*(page.getShowCount()));
//(8)查询数据库,返回对应检索姓名的数据
listApprover = ams.listSearchNameApprover(page);
}
mav.addObject("listApprover",listApprover); //返回对应条数的数据
mav.addObject("page",page); //返回对应的分页的内容
mav.addObject("deleteresult",pd.getString("delresult"));//返回批量删除操作后的结果
mav.addObject("addresult",pd.getString("addresult"));//返回添加审核人员操作后的结果
mav.setViewName("system/asystem_set/asystem_approver_list");
return mav;
}
备注:我这里用了自定义的PageDate对象,如果要用springmvc中的话,就用Model对象就可以了,只是用来返回数据到JSP中而已的。。。因为分页大部分是用于在显示数据的页面中的,所以我这里也是处理显示数据的用途的controller。。另外,我这里面还加入了检索的管理,对于这个部分可以忽略。(5)service层代码
1:获取数据的总条数
public Integer findTotalDataNumber() throws Exception {
return (Integer) dao.findForObject("ApproverManage.findTotalNumber", null);
}
2:获取对应的分页的内容数据
public List<PageData> listPdPageApprover(PageOption page) throws Exception{
return (List<PageData>) dao.findForList("ApproverManage.approverListPage" ,page);
}
(6)mybatis层的mapper代码
1:获取数据的总条数(这个随便写,根据自己的需要进行的是查询哪个数据库中的表即可,我这写的只是一个测试例子,告诉你们怎么写格式)
<select id="findTotalNumber" resultType="Integer">
select count(*)
from
sys_approver
</select>
2:获取分页数据的内容
<select id="approverListPage" parameterType="com.mbfw.entity.assets.PageOption" resultType="pd" usecache="false">
select *
from sys_approver
limit #{currentResult},#{showCount}
</select>
备注:mybatis中的这代码,主要就是告诉大家怎么用的而已,具体的查询哪个表还是根据自己的需要进行替换即可。简单点说,就是查询数据总条数和对应分页中的数据内容即可。。。很容易理解的
总结:针对上面的两种方法,大家可以根据需要进行选择,如果喜欢在JSP控制,就用第二种方法,如果喜欢在service层控制就用第一种即可。
相关阅读
YankRing,实现类似于Emacs的“kill ring”功能,配置如下 "YankRing "将yankring的历史文件夹移到~/.vim let g:yankring_history_
Unity Cinemachine插件学习笔记,结合Timeline实现简单
1. 轨道设置如图 0和4重合,模拟一个闭环。的属性都是用来看的,没有实际影响。Looped如果选择了,就会将第一个点和最后一个点连接。
转自 https://www.cnblogs.com/findumars/p/6254627.htmlvs2010 2013 2015+ 必备插件精选(15个)转 http://www.spersky.com/post/
JAVAWEB开发之工作流详解(一)——Activiti的环境搭建
工作流的概念 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按
Logo Grabber 一键快速下载网站Logo 的免费插件
很多小伙伴找网站或Logo 时,绝大多数人应该都是通过百度或者搜狗图片,现在有个更便捷的方式,最近国外就有开发者开发出Logo Grabber