Spring+Mybatis+jQuery.Pagination.js异步分页及JsonConfig的使用
在开发工作中经常用到异步分页,这里简单整理一下资料。
一、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>
展示: