
本博客介绍基于 Spring Data 这款 orm 框架加上 Jquery.pagination 插件实现的分页功能。
本博客是基于一款正在开发中的 github 开源项目的,项目代码地址: https://github.com/u014427391/jeeplatform 欢迎 star(收藏)或者可以下载去学习,还在开发...
介绍一下 Spring Data 框架 spring Data : Spring 的一个子项目。用于简化数据库访问,支持 NoSQL 和 关系数据存储。 下面给出 SpringData 项目所支持 NoSQL 存储:
SpringData 项目所支持的关系数据存储技术:
JPA Spring Data : 致力于减少数据访问层 (DAO) 的开发量。开发者只要写好持久层接口就好,然后其它的框架会帮程序员实现。
开发步骤: [ Spring Data 实现数据获取] 本项目是采用 maven 的,所以可以参考一下项目的 maven 配置:
设计好数据库,编写一个实体类:
package org.muses.jeeplatform.model.entity; import java.util.Date; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; /** * 用户信息的实体类 * @author Nicky */ @Entity @Table(name="sys_user") public class User { /** 用户 Id**/ private int id; /** 用户名**/ private String username; /** 用户密码**/ private String password; /** 手机号**/ private int phone; /** 性别**/ private String sex; /** 邮件**/ private String email; /** 备注**/ private String mark; /** 用户级别**/ private String rank; /** 最后一次时间**/ private Date lastLogin; /** 登录 ip**/ private String loginIp; /** 图片路径**/ private String imageUrl; /** 注册时间**/ private Date regTime; /** 账号是否被锁定**/ private Boolean locked = Boolean.FALSE; private Set<Role> roles; @GeneratedValue(strategy=GenerationType.IDENTITY) @Id public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(unique=true,length=100,nullable=false) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Column(length=100,nullable=false) public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getPhone() { return phone; } public void setPhone(int phone) { this.phOne= phone; } @Column(length=6) public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Column(length=100) public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Column(length=30) public String getMark() { return mark; } public void setMark(String mark) { this.mark = mark; } @Column(length=10) public String getRank() { return rank; } public void setRank(String rank) { this.rank = rank; } @Temporal(TemporalType.DATE) public Date getLastLogin() { return lastLogin; } public void setLastLogin(Date lastLogin) { this.lastLogin = lastLogin; } @Column(length=100) public String getLoginIp() { return loginIp; } public void setLoginIp(String loginIp) { this.loginIp = loginIp; } @Column(length=100) public String getImageUrl() { return imageUrl; } public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } @Temporal(TemporalType.DATE) @Column(nullable=false) public Date getRegTime() { return regTime; } public void setRegTime(Date regTime) { this.regTime = regTime; } public Boolean getLocked() { return locked; } public void setLocked(Boolean locked) { this.locked = locked; } } 编写接口实现 Spring Data 框架的 PagingAndSortingRepository 接口
package org.muses.jeeplatform.repository; import org.muses.jeeplatform.model.entity.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import java.util.Date; public interface UserRepository extends PagingAndSortingRepository<User, Integer> { /*User findByUsername(String username); @Query("from User u where u.username=:username and u.password=:password") User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password); @Query("from User u where u.id=:id") User findById(@Param("id") int id); @Query("from User u where date_format(u.lastLogin,'yyyy-MM-dd') between date_format((:startDate),'yyyy-MM-dd') and date_format((:endDate),'yyyy-MM-dd')") Page<User> searchU(@Param("startDate")Date startDate,@Param("endDate")Date endDate, Pageable pageable); */ } 业务类实现:
package org.muses.jeeplatform.service; import java.util.*; import org.muses.jeeplatform.model.entity.User; import org.muses.jeeplatform.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; /** * @description 用户信息管理的业务类 * @author Nicky * @date 2017 年 3 月 6 日 */ @Service public class UserService { @Autowired UserRepository userRepository; /** * 构建 PageRequest 对象 * @param num * @param size * @param asc * @param string * @return */ private PageRequest buildPageRequest(int num, int size, Sort.Direction asc, String string) { return new PageRequest(num-1, size,null,string); } /** * 获取所有的菜单信息并分页显示 * @param pageNo * 当前页面数 * @param pageSize * 每一页面的页数 * @return */ @Transactional public Page<User> findAll(int pageNo, int pageSize, Sort.Direction dir, String str){ PageRequest request = buildPageRequest(pageNo, pageSize, dir, str); Page<User> users = userRepository.findAll(request); return users; } } 控制类,采用 SpringMVC 框架,先编写一个 baseController,实现一些通用功能的封装:
package org.muses.jeeplatform.web.controller; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.ModelAndView; public class BaseController { Logger log = null; /** * 获取日志对象 * @return */ public Logger getInstance(){ if(log == null){ log = LoggerFactory.getLogger(BaseController.class); } return log; } /** * 得到 request 对象 */ public HttpServletRequest getRequest() { HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); return request; } /** * 得到 ModelAndView */ public ModelAndView getModelAndView(){ return new ModelAndView(); } } 控制类实现:
package org.muses.jeeplatform.web.controller; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import org.apache.commons.collections.map.HashedMap; import org.muses.jeeplatform.core.Constants; import org.muses.jeeplatform.core.ExcelViewWrite; import org.muses.jeeplatform.core.JavaEmailSender; import org.muses.jeeplatform.model.entity.User; import org.muses.jeeplatform.service.UserService; import org.muses.jeeplatform.utils.DateJsonValueProcessor; import org.muses.jeeplatform.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; 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 org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.*; /** * Created by Nicky on 2017/7/29. */ @RequestMapping("/user") @Controller public class UserController extends BaseController{ @Autowired UserService userService; /** * 查询所有管理员信息并分页显示 * @param request * @param response * @param model * @return */ @RequestMapping(value = "/queryAll",produces = "application/json;charset=") @ResponseBody public ModelAndView findAll(HttpServletRequest request, HttpServletResponse response, Model model){ //当前页 String pageIndexStr = request.getParameter("pageIndex"); //每一页的页数 int pageSize = Constants.PAGE_SIZE; ModelAndView mv = this.getModelAndView(); Page<User> userPage; if(pageIndexStr==null||"".equals(pageIndexStr)){ pageIndexStr = "0"; } int pageIndex = Integer.parseInt(pageIndexStr); userPage = userService.findAll(pageIndex+1, pageSize, Sort.Direction.ASC,"id"); mv.addObject("totalCount",userPage.getTotalElements()); mv.addObject("pageIndex",pageIndex); // JsonConfig cfg = new JsonConfig(); // cfg.setExcludes(new String[]{"handler","hibernateLazyInitializer"}); JsonConfig jcg = new JsonConfig(); jcg.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor("yyyy-mm-dd")); JSONArray jsOnArray= JSONArray.fromObject(userPage.getContent(),jcg); //System.out.println(jsonArray.toString()); mv.addObject("users",jsonArray.toString()); mv.setViewName("admin/user/sys_user_list"); return mv; } } [前端页面实现] 页面 View 实现,引用 jquery.pagination.js (分页 js ),跟 pagination.css (分页样式 css )。 可以去这里下载 http://www.cnblogs.com/knowledgesea/archive/2013/01/03/2841554.html
<%@ page cOntentType="text/html; charset=" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE html> <html lang="zh-CN"> <head> <base href="<%=basePath %>"> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" cOntent="IE=edge"> <meta name="viewport" cOntent="width=device-width,initial-scale=1"> <title>Insert title here</title> <!-- bootstrap 样式--> <link type="text/css" rel="stylesheet" href="<%=basePath%>plugins/page/css/bootstrap-3.3.5.min.css" /> <!-- jquery.pagination 所需 CSS --> <link type="text/css" rel="stylesheet" href="<%=basePath%>plugins/page/css/pagination.css" /> <script type="text/Javascript" src="<%=basePath%>plugins/page/js/jquery.min.js"></script> <!-- jquery.pagination 所需 JS 注意必须放在 jquery.js 后面 --> <script type="text/Javascript" src="<%=basePath%>plugins/page/js/jquery.pagination.js"></script> <script type="text/Javascript"> /** 分页操作,使用 jquery.pagination 插件 add by nicky 20170729 start **/ //当前页 var pageIndex = Number(${pageIndex}); //数据量 var totalCount = Number(${totalCount}); $(document).ready(function () { //加入分页的绑定 $("#Pagination").pagination(totalCount, { callback : pageselectCallback, prev_text : '< 上一页', next_text: '下一页 >', items_per_page : 6, num_display_entries : 6, current_page : pageIndex, num_edge_entries : 1, link_to: "user/queryAll?pageIndex=__id__" //分页的 js 中会自动把"__id__"替换为当前的数。0 }); var html = ""; var data = ${users}; $.each(data,function(idx,obj){ var id = obj.id; var username = obj.username; var mark = obj.mark; var phOne= obj.phone; var email = obj.email; var lastLogin = obj.lastLogin; var loginIp = obj.loginIp; html += "<tr><td><input type='checkbox' name='id' id='id' value=" + id + " /></td>" + "<td>"+id+"</td>"+ "<td>"+username+"</td>"+ "<td>"+mark+"</td>"+ "<td>"+phone+"</td>"+ "<td>"+email+"</td>"+ "<td>"+lastLogin+"</td>"+ "<td>"+loginIp+"</td>"+ "<td><a href='Javascript:openEditDialog("+id+");' class='bounceIn'>配置角色</a>"+ "</tr>"; }); $("#content").append(html); }); //这个事件是在翻页时候用的 function pageselectCallback(index, jq) { } /** 分页操作,使用 jquery.pagination 插件 add by nicky 20170729 end **/ //checkbox 的全选 /反选 var isCheckAll = false; function doCheck(){ if(isCheckAll){ $("input[type='checkbox']").each(function(){ this.checked = false; }); isCheckAll = false; }else{ $("input[type='checkbox']").each(function(){ this.checked = true; }); isCheckAll = true; } } </script> </head> <body> <br> <div class="container-fluid"> <div class="row"> <div class="col-xs-12 col-md-12"> <div class="panel panel-default"> <div class="panel-body"> <form class="form-inline"> <input type="button" class="btn btn-default" value="发送邮件" Onclick="sendEmail();" /> <input type="button" class="btn btn-default" value="发送短信" Onclick="sendSms();" /> <input type="button" class="btn btn-default" value="导出 Excel 表" Onclick="exportExcel();" /> <br><br><!-- <input type="text" class="form-control" id="keyword" placeholder="请输入关键词"> 日期从<input type="text" class="form-control" placeholder="请输入开始日期" value="${startdate }" id="startDate" name="startdate" Onclick="WdatePicker({dateFmt:'yyyy-MM-dd' ,maxDate:'#F{$dp.$D(\'endDate\')}'});"/> 到<input type="text" class="form-control" placeholder="请输入结束日期" value="${enddate }" id="endDate" name="enddate" Onclick="WdatePicker({dateFmt:'yyyy-MM-dd' ,minDate:'#F{$dp.$D(\'startDate\')}'});" /> <input type="button" class="btn btn-default" value="Search" Onclick="doSearch();"/>--> </form> <table class="table" id="mTable"> <thead> <tr> <th><input type="checkbox" Onclick="doCheck();" /></th> <th>序号</th> <th>用户名</th> <th>描述</th> <th>手机</th> <th>邮箱</th> <th>最近登录</th> <th>上次登录 IP</th> <th>操作</th> </tr> </thead> <tbody id="content"> </tbody> </table> <div id="Pagination" class="pagination"></div> <!-- demo --> </div> </div> </div> </div> </div> </body> </html> 前端页面展示:
ok,本博客是基于一款正在开发中的 github 开源项目的,项目代码地址: https://github.com/u014427391/jeeplatform 欢迎 star(收藏)或者可以下载去学习,不过还在开发...
1 evolify Dec 26, 2017 v2 上面都是不用 jq 的 |
2 acrisliu Dec 26, 2017 V2 不建议全文转载,建议直接贴你 CSDN 博客链接就好了,虽然 V2 的排版比 CSDN 好看很多。(逃 |
3 nicevar Dec 26, 2017 这种系统还是采用 ExtJS 开发最方便,你这分页还能写出一篇文章,ExtJS 里面直接一个控件放进去就搞定了,所有的逻辑已经跟 jpa 无缝对接了,不用自己写一句代码 |
4 jeffpan Dec 26, 2017 Spring MVC 太多冗余代码了,既然用 JPA,何不用 Spring Boot ? |
5 loveCoding Dec 26, 2017 这... 一个分页都能写篇文章啦 |
6 jalena Dec 26, 2017 代码写的好。! |
7 gbin Dec 26, 2017 via Android @loveCoding 都是从基础过来的 |
8 jalena Dec 26, 2017 话说既然都用 jquery,为毛不直接再用个 table 框架,,人家都找好了轮子了嘛! |
9 loveCoding Dec 26, 2017 @gbin #7 哈哈 ,没有嘲讽的意思 |
10 hantsy Dec 26, 2017 好多年没见 JSP 了,我快十年没用了,现在用的人还很多吗? JSP 本身从 J2EE1.4(2003 年)到现在,快 15 年没更新了。 差不多四五年前开始全部用 RESTful APIs + 前端 SPA 了。之前一段时间用模板技术比较多一些,freemarker, thymeleaf 都不错。 Spring 分页 Controller method 同样可以接受 Pageable, 只需要加入 Pageable 就可以获取分页参数, 直接添加 page 到 Model 中,返回就完了,在页面都可能用 SPEL 读取。 Spring Data 同样可以接受 Pageable, 返回 Page 就行了 。 哪这么麻烦? 这哪一年的 Spring ? BaseController 的 getInstance, getRequest,ModelAndView 这种垃圾代码, 我真的醉了。 早年使用 Struts 的人,对继承使用有切肤之痛,我早不再用这种无关紧要的继承。 Logger 一般在当然类中声明为 static final 即可(想简单一点用 Lombok Annotation ),Request,ModelAndView 直接注入到方法就行了。 findALL 注入了 Model, 又用 getModelAndView 来处理 Model ???@ResponseBody 和 produces="application/json" 是针对于 REST API 开发。而 ModelAndView 是为了处理传统 MVC。 混成一团,我真怀疑有没有读过 Spring 参考文档啊??? 哪怕读一次也不可能写出这种代码。 |
13 xuminzhong Dec 26, 2017 Java 写这种东西,冗余太多,不好看。 建议别使用 Spring,直接返回 JSON。 前端:html += "<tr><td><input type='checkbox' ...... 这种已经是上个世纪的写法了,非常难看。 建议你了解下数据驱动的写法,比如 vue.js 是个入门好选择。 |
14 xuminzhong Dec 26, 2017 另外,Java Bean 写 Web 是一种浪费资源多余的做法,建议直接 Map。 ( public class User...) 用接口写 Web 也是不推荐的,Java 有专门设计 Jsp tag 来处理这块东西,UserService、UserRepository 没必要存在。 |
15 2gMvqdiq91WfMHOd Dec 26, 2017 我艹,我的代码基本上就和楼主的差不多,看了楼上几位大神的回复,我感觉这几年代码白写了.... |