springmvc+jpa實現分頁的兩種方式


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);
    }
}
View Code

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;
    }
}
View Code

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;
}
View Code

  實現思路:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM