在开发工作中经常用到异步分页,这里简单整理一下资料。
一、Controller方法
package com.lwj.controller; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.lwj.entity.Member;
import com.lwj.page.Page;
import com.lwj.service.MemberService;
import com.lwj.util.json.PageJsonConfig; import net.sf.json.JSONObject; @Controller
@RequestMapping("/member")
public class MemberController extends BaseController {
private static final Logger log = LoggerFactory.getLogger(MemberController.class); @Autowired
private MemberService memberService; @RequestMapping("/list")
public String list() {
return "member/list";
} @RequestMapping("/getList")
public @ResponseBody JSONObject getMembersByPage(HttpServletRequest requet, HttpServletResponse response,
Page<Member> page) {
try {
if (page == null) {
page = new Page<Member>();
}
page = memberService.findListByPage(page);
JSONObject jsonObject = JSONObject.fromObject(page, new PageJsonConfig());//JsonConfig注册分页相应类型为null的处理类
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return null;
} @RequestMapping("/add")
public String add() {
return "member/add";
} /**
* 添加用户
*
* @param requet
* @param response
* @param member
* @return
*/
@RequestMapping("/save")
public @ResponseBody String save(HttpServletRequest requet, HttpServletResponse response, Member member) {
try {
int num = memberService.addMember(member);
if (num == 0) {
return "failed";
}
return "success";
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return "error";
}
}
二、Dao实现类
package com.lwj.dao.impl; import java.io.Serializable;
import java.util.List; import org.springframework.stereotype.Repository; import com.lwj.dao.MemberDao;
import com.lwj.entity.Member;
import com.lwj.page.Page; /**
*
* @Description : MemberDao实现类
* @author : liwenjian
* @version : 1.0
* @Date : 2016年1月28日 下午3:22:04
* @param <T>
* @param <PK>
*/
@Repository
public class MemberDaoImpl<T, PK extends Serializable> extends BaseDaoImpl<Member, Integer>
implements MemberDao<Member, Integer> {
/**
* 获取Mapper.xml默认的空间
*/
private String namespace = getDefaultSqlNamespace(); @Override
public List<Member> getMembers() throws Exception {
return super.select();
} @Override
public int insertMember(Member member) throws Exception {
return super.insert(member);
} @Override
public int updateMember(Member member) throws Exception {
return super.update(member);
} @Override
public Member findMemberByName(String name) throws Exception {
return getSqlSession().selectOne(namespace + ".findByName", name);
} @Override
public List<Member> findListByEmail(String email) throws Exception {
return getSqlSession().selectList(namespace + ".findListByEmail", email);
} @Override
public Page<Member> findListByPage(Page<Member> page) throws Exception {
List<Member> list = getSqlSession().selectList(namespace + ".findListByPage", page);
if (page != null && page.getTotalSize() == 0) {
Integer totalSize = getSqlSession().selectOne(namespace + ".findCountByPage", page);
page.setTotalSize(totalSize);
}
page.setList(list);
return page;
} }
三、Member实体
package com.lwj.entity; import java.io.Serializable; /**
*
* @Description : 用户实体
* @author : liwenjian
* @version : 1.0
* @Date : 2016年1月28日 下午3:06:48
*/
public class Member extends BaseEntity implements Serializable { /**
* serialVersionUID:TODO
*
* @since 1.0.0
*/ private static final long serialVersionUID = 1L; private String memberName;
private String memberPassword;
private String memberEmail;
private Integer memberBirthday;
private Integer memberSex; public String getMemberName() {
return memberName;
} public void setMemberName(String memberName) {
this.memberName = memberName;
} public String getMemberPassword() {
return memberPassword;
} public void setMemberPassword(String memberPassword) {
this.memberPassword = memberPassword;
} public String getMemberEmail() {
return memberEmail;
} public void setMemberEmail(String memberEmail) {
this.memberEmail = memberEmail;
} public Integer getMemberBirthday() {
return memberBirthday;
} public void setMemberBirthday(Integer memberBirthday) {
this.memberBirthday = memberBirthday;
} public Integer getMemberSex() {
return memberSex;
} public void setMemberSex(Integer memberSex) {
this.memberSex = memberSex;
} }
四、Mapper XML
<?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.lwj.entity.MemberMapper">
<!-- 开启二级缓存 -->
<cache />
<resultMap type="com.lwj.entity.Member" id="memberResult">
<id column="id" property="id" />
<result column="member_name" property="memberName" />
<result column="member_password" property="memberPassword" />
<result column="member_email" property="memberEmail" />
<result column="member_birthday" property="memberBirthday" />
<result column="member_sex" property="memberSex" />
<result column="create_date" property="createDate" />
<result column="modify_date" property="modifyDate" />
</resultMap>
<!-- 查询列表 -->
<select id="select" resultMap="memberResult">
SELECT * FROM t_member
</select>
<!-- 保存对象 -->
<insert id="insert" parameterType="com.lwj.entity.Member">
INSERT INTO t_member
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="memberName != null">
member_name,
</if>
<if test="memberPassword != null">
member_password,
</if>
<if test="memberEmail != null">
member_email,
</if>
<if test="memberBirthday != null">
member_birthday,
</if>
<if test="memberSex != null">
member_sex,
</if>
<if test="createDate != null">
create_date,
</if>
<if test="modifyDate != null">
modify_date,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="memberName != null">
#{memberName},
</if>
<if test="memberPassword != null">
#{memberPassword},
</if>
<if test="memberEmail != null">
#{memberEmail},
</if>
<if test="memberBirthday != null">
#{memberBirthday},
</if>
<if test="memberSex != null">
#{memberSex},
</if>
<if test="createDate != null">
#{createDate},
</if>
<if test="modifyDate != null">
#{modifyDate},
</if>
</trim> </insert>
<!-- 根据ID查询对象 -->
<select id="selectPk" resultMap="memberResult" parameterType="java.lang.Integer">
select * from t_member where id = #{id}
</select>
<!-- 根据ID更新对象 -->
<update id="update" parameterType="com.lwj.entity.Member">
update t_member
<set>
<if test="memberName != null">
member_name = #{memberName},
</if>
<if test="memberPassword != null">
member_password = #{memberPassword},
</if>
<if test="memberEmail != null">
member_email = #{memberEmail},
</if>
<if test="memberBirthday != null">
member_birthday = #{memberBirthday},
</if>
<if test="memberSex != null">
member_sex = #{memberSex},
</if>
<if test="createDate != null">
create_date = #{createDate},
</if>
<if test="modifyDate != null">
modify_date = #{modifyDate}
</if>
</set>
where id = #{id}
</update>
<!-- 根据用户名称查询 -->
<select id="findByName" parameterType="java.lang.String"
resultMap="memberResult">
select * from t_member
where member_name = #{name}
</select>
<!-- 根据用户邮箱查询 -->
<select id="findListByEmail" parameterType="java.lang.String"
resultMap="memberResult">
select * from t_member
where member_email = #{email}
</select>
<!-- 根据用户条件查询分页 -->
<select id="findListByPage" parameterType="com.lwj.page.Page"
resultMap="memberResult">
select * from t_member
where 1=1
<if test="condition!=null">
<if test="condition.memberName!=null and condition.memberName!=''">
and member_name = #{condition.memberName}
</if>
<if test="condition.memberPassword!=null and condition.memberPassword!=''">
and member_password = #{condition.memberPassword}
</if>
<if test="condition.memberEmail!=null and condition.memberEmail!=''">
and member_email = #{condition.memberEmail}
</if>
</if>
limit #{offSet},#{pageSize}
</select>
<!-- 根据用户条件查询总数 -->
<select id="findCountByPage" parameterType="com.lwj.page.Page"
resultType="java.lang.Integer">
select count(1) from t_member
where 1=1
<if test="condition!=null">
<if test="condition.memberName!=null and condition.memberName!=''">
and member_name = #{condition.memberName}
</if>
<if test="condition.memberPassword!=null and condition.memberPassword!=''">
and member_password = #{condition.memberPassword}
</if>
<if test="condition.memberEmail!=null and condition.memberEmail!=''">
and member_email = #{condition.memberEmail}
</if>
</if>
</select>
</mapper>
五、Page分页类
package com.lwj.page; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; public class Page<T> implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8036358745002950680L; private static final Integer MIN_PAGE = 1;// 最小页数 private static final Integer DEFAULT_PAGE_SIZE = 20;// 默认每页显示20条数据 private static final Integer TOTAL_SIZE = 0;// 总数据数 /**
* 当前页码
*/
private Integer currentPage = MIN_PAGE; /**
* 每页显示数
*/
private Integer pageSize = DEFAULT_PAGE_SIZE; /**
* limit的开始位置
*/
private Integer offSet; /**
* 总数据数
*/
private Integer totalSize; /**
* 实体条件
*/
private T condition; /** 结果集 */
private List<T> list = new ArrayList<T>(); /**
* 获取当前页码
*
* @return 当前页码
*/
public Integer getCurrentPage() {
if (this.currentPage != null && this.currentPage >= 1) {
return currentPage;
}
return MIN_PAGE;
} /**
* 设置当前页码
*
* @param currentPage
* 当前页码
*/
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
} /**
* 获取每页显示数
*
* @return 每页显示数
*/
public Integer getPageSize() {
if (this.pageSize != null && this.pageSize >= 1) {
return this.pageSize;
}
return DEFAULT_PAGE_SIZE;
} /**
* 设置每页显示数
*
* @param pageSize
* 每页显示数
*/
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
} public Integer getOffSet() {
offSet = (this.getCurrentPage() - 1) * this.getPageSize();
return offSet;
} public void setOffSet(Integer offSet) {
this.offSet = offSet;
} /**
* 获取总条数
*
* @return 总条数
*/
public Integer getTotalSize() {
if (this.totalSize != null && this.totalSize >= 0) {
return this.totalSize;
}
return TOTAL_SIZE;
} /**
* 设置总条数
*
* @param totalSize
* 总条数
*/
public void setTotalSize(Integer totalSize) {
this.totalSize = totalSize;
} /**
* 获取实体条件
*
* @return 实体条件
*/
public T getCondition() {
return condition;
} /**
* 设置实体条件
*/
public void setCondition(T condition) {
this.condition = condition;
} /**
* 获取结果集
*
* @return 结果集
*/
public List<T> getList() {
return list;
} /**
* 设置结果集
*
* @param list
* 结果集
*/
public void setList(List<T> list) {
this.list = list;
} }
六、PageJsonConfig分页JsonConfig处理类
package com.lwj.util.json; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; import net.sf.json.JSONNull;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor; /**
* PageJsonConfig分页转换成JSON处理类
*
* @Description :JsonConfig类重写
* @author : liwenjian
* @version : 1.0
* @Date : 2016年5月6日 上午9:44:31
*/
public class PageJsonConfig extends JsonConfig {
public PageJsonConfig() {
// 可同时注册处理多种数据
this.registerJsonValueProcessor("condition", new EntityJsonValueProcessor());// 注入处理动态实体类condition=null
this.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor());// 注入处理Date类
} /**
*
* @Description :JSONArray.fromObject()转换异常,时间类型空值处理类
* @author : liwenjian
* @version : 1.0
* @Date : 2016年5月6日 上午9:34:26
*/
public class DateJsonValueProcessor implements JsonValueProcessor { @Override
public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
return process(obj);
} @Override
public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
return process(obj);
} private Object process(Object obj) {
if (obj == null) {// 如果时间为null,则返回空字串
return "";
}
if (obj instanceof Date) {
obj = new java.util.Date(((Date) obj).getTime());
}
if (obj instanceof java.util.Date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);// 格式化时间为yyyy-MM-dd类型
return sdf.format(obj);
} else {
return new Object();
}
} } /**
*
* @Description :实体类条件condition处理类,为空则返回""
* @author : liwenjian
* @version : 1.0
* @Date : 2016年5月6日 下午3:41:35
*/
public class EntityJsonValueProcessor implements JsonValueProcessor { @Override
public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
return obj;
} @Override
public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
if ("condition".equals(s)) {// com.lwj.page.Page分页类里面的condition动态实体对象,这里是以key的方式,如果condition为com.excenon.entity.Member类,则obj为传入的是com.lwj.entity.Member对象
return JSONNull.getInstance().equals(obj) ? "" : JSONObject.fromObject(obj, new PageJsonConfig());//为了方便这里就直接调用 new PageJsonConfig(),不再编写另一个处理null的Date类型的类,PageJsonConfig中的DateJsonValueProcessor方法处理null Date类型
}
return obj;
} }
}
七、异步分页jQuery.Pagination.js的list.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>用户列表</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<link rel="stylesheet" type="text/css"
href="<%=path%>/resources/js/jquery/pagination.css">
<script type="text/javascript"
src="<%=path%>/resources/js/jquery/jquery-1.8.3.min.js"></script>
<script type="text/javascript"
src="<%=path%>/resources/js/jquery/jquery.pagination.js"></script> <script type="text/javascript">
var total_size = 0;//总数据条数
var page_size = 30;//每页显示数
var pageIndex = 0;//当前页码
$(document).ready(function() {
//初始化分页,展示分页信息并动态获取总数据条数、每页展示条数
initPagination(pageIndex);
//初始化分页插件
$("#Pagination").pagination(total_size, {
callback : pageselectCallback,
prev_text : '上一页',
next_text : '下一页',
link_to : 'javascript:void(0);',//分页的链接,默认“#”
items_per_page : page_size,//每页显示的条目数
num_display_entries : 5,//连续分页主体部分显示的分页条目数
current_page : pageIndex,//当前选中的页面
num_edge_entries : 1//两侧显示的首尾分页的条目数
});
});
/**
*分页插件回调方法,page_index为当前页码
*/
function pageselectCallback(page_index, jq) {
initPagination(page_index);
}
/**
*初始化分页,展示分页信息并动态获取总数据条数、每页展示条数
*/
function initPagination(page_index) {
$.ajax({
url : "./member/getList.html",
data : {
currentPage : page_index + 1,
pageSize : page_size,
totalSize : total_size
},
type : "GET",
dataType : "json",
async : false,
success : function(data) {
if (!$.isEmptyObject(data)) {
page_size = data.pageSize;
total_size = data.totalSize;
var htmlStr = "";
$.each(data.list, function(i, item) {
htmlStr += "<li>ID:" + item.id + " 名称:" + item.memberName + " 密码:" + item.memberPassword +" 创建时间:" + item.createDate +"<li/>";
});
$("#list").html(htmlStr);
} else {
alert("没有获取到相关信息!");
}
}
});
}
</script> </head> <body>
<center>
<ul id="list" style="list-style-type: none;">
</ul>
<div id="Pagination" class=""></div>
</center>
</body>
</html>
展示: