1.工具类

public final class QueryTool {
public static PageRequest buildPageRequest(int pageNumber, int pageSize, String sortType){
Sort sort = null;
if("auto".equals(sortType)) {
sort = new Sort(Direction.DESC, "ctime");
} else {
sort = new Sort(Direction.DESC, "ctime");
} return new PageRequest(pageNumber, pageSize, sort);
} public static <T> Specification<T> buildSpecification(Map<String, Object> searchParams, Class<T> domainClass){
Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
Specification<T> spec = DynamicSpecifications.bySearchFilter(filters.values(), domainClass);
return spec;
}
}

2.Service类(只给出CommentService)

@Service
public class CommentService {
@Autowired
private CommentDao commentDao; @Transactional
public void addComment(Comment comment) {
if(comment == null) return;
commentDao.save(comment);
} @Transactional
public Page<Comment> findAllComments(String problemId, PageRequest pageable){
Page<Comment> page = commentDao.findAllCommentsByProblemId(problemId, pageable);
return page;
}
}

3.repository类(problem 和 comment 属于 一对多 的关系)

@Repository
public interface CommentDao extends JpaSpecificationExecutor<Comment>,
PagingAndSortingRepository<Comment, String> { @Query("select c from Comment c where c.problem.problemid = ?1")
public Page<Comment> findAllCommentsByProblemId(String problemId, Pageable pageable);
}

4.Controller类

  第一种方式

@Controller
public class ProblemController { @Autowired
private ProblemService problemService; @Autowired
private CommentService commentService; @RequestMapping(value="getCurProblemComments")
@ResponseBody
public String getCurProblemComments(String problemName, @RequestParam(value = "pn", defaultValue = "1") int pageNumber,
@RequestParam(value = "ps", defaultValue = "4") int pageSize,
@RequestParam(value = "sortType", defaultValue = "auto") String sortType){
JSONObject jsono = new JSONObject();
try {
Problem problem = problemService.getProblemByName(problemName);
if(problem == null){
problem = problemService.addProblem(problemName);
}
PageRequest pageRequest = QueryTool.buildPageRequest(pageNumber, pageSize, sortType);
//根据题目的id获取所有的评论
Page<Comment> page = commentService.findAllComments(problem.getProblemid(), pageRequest);
//对 Comment 这个类中的一些字段进行过滤
SimplePropertyPreFilter spp = new SimplePropertyPreFilter();
spp.getExcludes().addAll(Comment.getExcludeString());
jsono.put("success", true);
jsono.put("message", JSON.toJSONString(page, spp));
} catch(Exception e){
e.printStackTrace();
jsono.put("success", false);
jsono.put("message", "inner error.");
}
return jsono.toString();
}
}

  

  第二种方式,(懒了,有些内容是放在servic中的。)

  通过JpaSpecificationExecutor<T> 的Page<T> findAll(Specification<T> spec, Pageable pageable); 方法(按照指定的规格条件)实现分页查询。

public String getCurProblemComments(@RequestParam(value = "pn", defaultValue = "1") int pageNumber,
@RequestParam(value = "ps", defaultValue = "2") int pageSize,
@RequestParam(value = "sortType", defaultValue = "auto") String sortType, ServletRequest request) {
Map<String, Object> searchParams = new HashMap<String, Object>();
searchParams = Servlets.getParametersStartingWith(request, "search_");
System.out.println(EncodeUtils.toUTF8((String)searchParams.get("LIKE_name")));
PageRequest pageRequest = QueryTool.buildPageRequest(pageNumber, pageSize, sortType);
searchParams.put(Operator.EQ + "_dr", "0");//逻辑删除中,字段dr=0表示这条数据没有删除
Specification<Comment> spec = QueryTool.buildSpecification(searchParams, Comment.class);
Page<Comment> page = commentDao.findAll(spec, pageRequest);
return JSON.toJSONString(page);
}

  其中,Specification中的一些比较操作org.springside.modules.persistence.SearchFilter.Operator这个类中找到,如下:

public static enum Operator {
EQ, LIKE, GT, LT, GTE, LTE;
}

  前台传递过来的参数名称中可以包含 Operator 中的一些操作, 比如参数名称是: search_LIKE_name (search表示要查询时比较, LIKE是比较的操作, name是表的字段名)。

5.java简单实现分页

分页面板类(MyPagePanel.java)

public class MyPagePanel extends JPanel{
private final int PAGE_BTN_NUM = 6;//按钮的数目的最大值, 一定为偶数
private JButton[] pageBtns = new JButton[PAGE_BTN_NUM];
private JButton preBtn = new JButton("<<");//前一页
private JButton nextBtn = new JButton(">>");//后一页 private JButton jumpBtn = new JButton("跳转");
private JTextField jumpText = new JTextField(5);//输入页号
private JLabel totPageLabel = new JLabel("共0页");//提示一共多少页 public static final int PAGE_SIZE = 2;
private CommunicationPanel parentPanel;
private ChatPanel chatPanel;
//刷新某页
public void refreshPage(){
if(curPage == -1){
JOptionPane.showMessageDialog(null, "请选择题目,然后再刷新!", "温馨提示",JOptionPane.WARNING_MESSAGE);
} else {
requestPage(curPage);
}
}
//请求某页
public void requestPage(int pageNumber){
//当前页按钮设为 true
if(curBtnPos >= 0)
pageBtns[curBtnPos].setEnabled(true); JSONObject jsono = new JSONObject();
jsono.put("problemName", JavaRequest.problemName);
jsono.put("pageSize", String.valueOf(PAGE_SIZE));
jsono.put("pageNumber", String.valueOf(pageNumber));
String data = JavaRequest.sendPost("getCurProblemComments", jsono); //获取当前题目的 评论记录
JSONObject result = JSONObject.fromObject(data);
if((Boolean) result.get("success")){//分页显示
JSONObject message = JSONObject.fromObject(result.get("message"));
Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
classMap.put("content", MyMessage.class);
MyPage myPage = (MyPage) JSONObject.toBean(message, MyPage.class, classMap);
this.updatePage(myPage);
} else {
JOptionPane.showMessageDialog(null, result.getString("message"), "温馨提示",JOptionPane.WARNING_MESSAGE);
if(result.get("returnLogin") != null && (Boolean)result.get("returnLogin")){//如果用户登录超时返回用户登陆界面
parentPanel.switchPanel(CommunicationPanel.LOGIN_PANEL);
}
}
}
//跳转都页面
private void jumpPage(int pageNumber) throws Exception{
if(pageNumber < 0 || pageNumber >= totalPages)
throw new Exception("不存在该页号!");
requestPage(pageNumber);
} public MyPagePanel(CommunicationPanel parentPanelx, ChatPanel chatPanelx){
this.parentPanel = parentPanelx;
this.chatPanel = chatPanelx; preBtn.setEnabled(false);
this.add(preBtn);
preBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
requestPage(curPage-1);
}
}); for(int i=0; i<pageBtns.length; ++i) {
pageBtns[i] = new JButton();
this.add(pageBtns[i]);
pageBtns[i].setVisible(false);
pageBtns[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//JButton text 表示的是页号
String text = ((JButton)e.getSource()).getText();
int pageNumber = Integer.valueOf(text);
requestPage(pageNumber);
}
});
} nextBtn.setEnabled(false);
this.add(nextBtn);
nextBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
requestPage(curPage+1);
}
}); jumpBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try{
if(jumpText.getText().isEmpty()) throw new Exception("页数不能为空!");
int pageNumber = Integer.valueOf(jumpText.getText());
jumpPage(pageNumber);
} catch (Exception ex){
ex.printStackTrace();
JOptionPane.showMessageDialog(null, "请确定页号是否正确!", "温馨提示",JOptionPane.WARNING_MESSAGE);
}
}
});
this.add(totPageLabel);
this.add(jumpText);
this.add(jumpBtn);
}
private int curPage = -1, totalPages, curBtnPos = -1;
public void updatePage(MyPage myPage){
//清除当页面的信息
chatPanel.getJpChat().setText("");
//处理接受到的 评论消息
for(MyMessage message : myPage.getContent()){
chatPanel.addRecMsg(message.getCcontent(), StyleConstants.ALIGN_LEFT);
} curPage = myPage.getNumber();
totalPages = myPage.getTotalPages();
totPageLabel.setText("共" + totalPages + "页"); if(curPage == 0) preBtn.setEnabled(false);
else preBtn.setEnabled(true); if(curPage == totalPages-1 || totalPages == 0) nextBtn.setEnabled(false);
else nextBtn.setEnabled(true); List<Integer> pageNum = new LinkedList<Integer>();
if(totalPages > 0) {
int step = PAGE_BTN_NUM/2-1;
for(int i=step; i>=1; --i) {
if(curPage-i>=0)
pageNum.add(curPage-i);
} pageNum.add(curPage); for(int i=1; i<=step+1 && curPage+i<totalPages; ++i)
pageNum.add(curPage+i); if(pageNum.size() < PAGE_BTN_NUM){
while(pageNum.size() < PAGE_BTN_NUM && pageNum.get(0)-1 >= 0)
pageNum.add(0, pageNum.get(0)-1); while(pageNum.size() < PAGE_BTN_NUM && pageNum.get(pageNum.size()-1)+1 < totalPages)
pageNum.add(pageNum.get(pageNum.size()-1)+1);
}
} int bi = 0;
for(int pi=0; pi < pageNum.size(); ++pi, ++bi){
pageBtns[bi].setText(String.valueOf(pageNum.get(pi)));
if(pageNum.get(pi) == curPage){
curBtnPos = bi;//记录这个按钮的页号值 和 当前页号值相等
}
}
//重新显示按钮
for(int i=0; i<bi; ++i)
pageBtns[i].setVisible(true); //后面这些按钮都是没有 用上的
for(int i=bi; i < pageBtns.length; ++i){
pageBtns[i].setVisible(false);
} if(totalPages > 0)
pageBtns[curBtnPos].setEnabled(false);
}
}

MyMessage.class

public class MyMessage{
private String ccontent;
private String commentid;
public String getCcontent() {
return ccontent;
}
public void setCcontent(String ccontent) {
this.ccontent = ccontent;
}
public String getCommentid() {
return commentid;
}
public void setCommentid(String commentid) {
this.commentid = commentid;
}
}

MyPage.class

public class MyPage{
private List<MyMessage> content;
private boolean first;
private boolean last;
private int number;
private int numberOfElements;
private int size;
private String totalElements;
private String sort; public String getSort() {
return sort;
} public void setSort(String sort) {
this.sort = sort;
} public List<MyMessage> getContent() {
return content;
} public void setContent(List<MyMessage> content) {
this.content = content;
} public boolean isFirst() {
return first;
} public void setFirst(boolean first) {
this.first = first;
} public boolean isLast() {
return last;
} public void setLast(boolean last) {
this.last = last;
} public int getNumber() {
return number;
} public void setNumber(int number) {
this.number = number;
} public int getNumberOfElements() {
return numberOfElements;
} public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
} public int getSize() {
return size;
} public void setSize(int size) {
this.size = size;
} public String getTotalElements() {
return totalElements;
} public void setTotalElements(String totalElements) {
this.totalElements = totalElements;
} public int getTotalPages() {
return totalPages;
} public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
} private int totalPages;
}

  实现思路:

1. 首先看一下后台的json数据的格式(其中message的值是spring Data JPA分页查询结果的json)

{"success":true,"message":{"content":[{"ccontent":"hjz 2016-38-11 15:38:21*****宋体|12|0-0-0| *****0$$$$$70#####","commentid":"8ae45d92549da2a801549ec092ce001f"},{"ccontent":"hjz 2016-38-11 15:38:10*****宋体|12|0-0-0|哇哇 *****2$$$$$55#####","commentid":"8ae45d92549da2a801549ec068c7001e"}],"first":true,"last":false,"number":0,"numberOfElements":2,"size":2,"sort":{},"totalElements":8,"totalPages":4}}

2. 将“message”对应的值转换成MyPage对象,因为MyPage中有一个List<MyMessage>,如果属性中含有复杂的类型,当其中属性有类似List , Map ,ArrayList、自定义的类型,如List<MyMessage> content, 普通的转换会报错:java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to XXX,在JSONObject.toBean的时候如果转换的类中有集合,可以先定义Map<String, Class> classMap = new HashMap<String, Class>();在classMap中put你要转换的类中的集合名 。本例中需要将“content”对应的值转换成 MyMessage对象。

//data为后台的json串
JSONObject result = JSONObject.fromObject(data);
if((Boolean) result.get("success")){//分页显示
JSONObject message = JSONObject.fromObject(result.get("message"));
Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
classMap.put("content", MyMessage.class);
MyPage myPage = (MyPage) JSONObject.toBean(message, MyPage.class, classMap);
this.updatePage(myPage);
}

3.然后通过分页的信息,简单的实现分页按钮,详情看MyPagePanel.java

springmvc+jpa实现分页的两种方式的更多相关文章

  1. 【Spring】SpringMVC非注解配置的两种方式

    目录结构: contents structure [+] SpringMVC是什么 Spring MVC的设计原理 SpringMVC配置的第一种方式 1,复制Jar包 2,Web.xml文件 3,M ...

  2. SpringMVC配置字符过滤器的两种方式

    有时候使用SpringMVC框架提交表单时会出现中文乱码,以下是我亲自试验过的配置字符过滤器的两种: 1.在web.xml中配置 <filter> <filter-name>c ...

  3. springmvc获取资源文件的两种方式(超简单)

    1 比如我们在sc目录下新建一个db.properties文件内容如下 DriverClass=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306 ...

  4. springmvc+druid+dataSource配置的两种方式

    一.一般的配置方式 数据库连接配置在jdbc.properties文件中,这种方式有一个最大的缺点,数据库的配置信息对开发人员是完全可见的,十分方便程序员删库跑路.spring配置具体如下: 1.jd ...

  5. yii2-搜索带分页,分页的两种方式

    1.文章表关联 <?php //...other code //关联 public function getCate(){ return $this->hasOne(ArticleCate ...

  6. django分页的两种方式

    第一种自定义分页: def pageDemo(request): ''' 自定义分页] :param request: :return: ''' currentpage=request.GET.get ...

  7. ibatis分页的两种方式

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  8. oracle 分页的两种方式

    实例:查询5-8名学生的姓名与成绩 --oracle的分页1 between 方式(分三次查询,第一次只作排序,第二次给表加上rownum序列,第三次为查询结果) select s.scorenumb ...

  9. mysql中用limit 进行分页有两种方式

    代码示例:语句1: select * from student limit 9,4 语句2: slect * from student limit 4 offset 9 // 语句1和2均返回表stu ...

随机推荐

  1. PHP验证用户登录例子-学习笔记

    1.基本流程: 2.UML类图: 3.PHP代码: 3.1 index.php <?php /** * Created by PhpStorm. * User: andy * Date: 16- ...

  2. 前端学HTTP之日志记录

    前面的话 几乎所有的服务器和代理都会记录下它们所处理的HTTP事务摘要.这么做出于一系列的原因:跟踪使用情况.安全性.计费.错误检测等等.本文将谥介绍日志记录 记录内容 大多数情况下,日志的记录出于两 ...

  3. Android业务组件化之子模块SubModule的拆分以及它们之间的路由Router实现

    前言: 前面分析了APP的现状以及业务组件化的一些探讨(Android业务组件化之现状分析与探讨),以及通信的桥梁Scheme的使用(Android业务组件化之URL Scheme使用),今天重点来聊 ...

  4. 构建通用的 React 和 Node 应用

    这是一篇非常优秀的 React 教程,这篇文章对 React 组件.React Router 以及 Node 做了很好的梳理.我是 9 月份读的该文章,当时跟着教程做了一遍,收获很大.但是由于时间原因 ...

  5. golang语言构造函数

    1.构造函数定义 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个构造函数 ,可根据其参数个 ...

  6. Mono下的WCF的Bug?

    最近一段时间,一直在折腾Mono,折腾Linux.让我无比痛苦的是Mono下的WCF的坑真的是太多了,这不又遇到了一个莫名其妙的问题. 环境:mono 3.2.1,Jexus 5.4.3,OS Cen ...

  7. 最新Linux部署.NET,Mono and DNX

    这几天一直在折腾在Linux下的ASP.NET 5,就下在看来在其它操作系统中ASP.NET 5或.NET应用,要想在完整的MS VM(CoreCLR)上运行还不远远达不到,应用的效果. 目前只能在M ...

  8. ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus

    ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus 本文承接我的上一篇博文: ASP.NET 5 Linux部署,那篇文章主要是针对最新的ASP. ...

  9. .NET面试题系列[2] - .NET框架基础知识(2)

    3 程序集 面试出现频率:虽然很重要但不怎么出现,可能会考你定义,以及程序集包括什么,然后自然的话题就跑到反射上去了. 重要程度:8/10,很重要 需要理解的程度:知道程序集包括IL和元数据.知道元数 ...

  10. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...