1. 程式人生 > >java-web專案的分頁與聯合模糊查詢(不使用分頁框架)

java-web專案的分頁與聯合模糊查詢(不使用分頁框架)

記錄分頁的一種例項解決方案:
專案背景:書籍後臺管理系統
專案資料庫:mysql
專案框架:spring、spring-mvc、mybatis
開發模式:三層架構(controller層、service層、dao層)

一、準備工作-dto類

1.接收內容的實體類-Sold.java:

```
package com.bookstore.dto;

import java.util.Date;
public class Sold {

private int userid;
private int bookid;
private String uname;
private String bname;
private int number = 1;
private Date time;
private Date beginDate;//聯合查詢的開始時間
private Date endDate;//聯合查詢的結束時間
private int startPage;//翻頁時的開始內容位置
private int endPage;//翻頁時的結束內容位置
private double price;
private double allprice;
private String author;
private String press;
}

```
//注:此實體類僅寫出引數(其他有參無參自己腦補下就好了ー( ̄~ ̄)ξ)    

2.翻頁用的實體類-Paging.java:

```
package com.bookstore.dto;

public class Paging {
    //也可以將此類引數定義為private
    public int currentPage = 1;//當前頁
    public int rowsPage = 10;//每頁顯示數
    public int allCount;//總記錄數
    public int maxPage;//總頁數

    //這是一個根據前臺頁面傳遞過來的頁面數計算顯示內容起始位置的方法
    public void getPage(int currentPage,Sold sold){
        int start = (currentPage - 1)*rowsPage;
        sold.setStartPage(start);
        sold.setEndPage(rowsPage);
        System.out.println("起始頁:"+start);
    }
}
```

二、jsp頁面的主要內容
注:jsp添加了此標頭檔案以獲取當前頁面地址

```
    <%
    //獲取當前系統路徑
    String path = request.getContextPath();
    // 獲取當前協議名(預設http) 獲取瀏覽器顯示的主機名  獲取伺服器埠號
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/";
    %>  
```

1、聯合模糊查詢模組:
```
<tr>
  <td>
  <form action="<%=basePath %>manager/selectSold.action" method="post">
      <table style="font-size: 16px;">
      <tr>
          <td align=left>使用者名稱</td>
          <td><input type="text" name="uname" value="${uname}"/></td>
      </tr>
      <tr>
          <td align=left>開始日期 </td>
          <td>
          <input type="text" name="beginDate" value="${beginDate}"/>
          </td> 
          <td align=left>結束日期 </td>
          <td>
          <input type="text" name="endDate" value="${endDate}"/></td>
          <td><input type=submit value="查詢"/></td>
      </tr>
      </table>
  </form>
  </td>
</tr>
```
2.內容顯示模組與翻頁:
```
<table border="1" width=100%> 

       <tr>
           <td>使用者名稱</td>
           <td>書名--購買數量(本)</td>
           <td>書單價</td>
           <td>出版社</td>
           <td>作者</td>
           <td>購買日期</td>
           <td>總付款</td>
       </tr>
        <c:forEach var="br" items="${records}">
          <tr>
            <td>${br.uname}</td>
            <td>${br.bname}--${br.number}</td>
            <td>${br.price}</td>
            <td>${br.press}</td>
            <td>${br.author}</td>
            <td>${br.time}</td>
            <td>${br.allprice}</td>
          </tr>
         </c:forEach>

        <tr>
        <td>
        <table id="tblTurnPage">                
            <tr>
                <td>總記錄數:${allCount}</td> 
                <td>總頁數:${maxPage}</td>
                <td>當前頁:${currentPage}</td>
                <td>
                <a href="<%=basePath%>manager/turnPage.action?currentPage=1&maxPage=${maxPage}">首頁</a>
                <a href="<%=basePath%>manager/turnPage.action?currentPage=${currentPage-1}&maxPage=${maxPage}">≮前頁</a>
                <a href="<%=basePath%>manager/turnPage.action?currentPage=${currentPage+1}&maxPage=${maxPage}">後頁≯</a>
                <a href="<%=basePath%>manager/turnPage.action?currentPage=${maxPage}&maxPage=${maxPage}">末頁</a>
                </td>
            </tr>               
        </table>            
        </td>
      </tr>
    </table> 
```

三、controller主要方法體

1、這是controller的開頭

@Controller
@RequestMapping("/manager/")
public class ManagerAction {
    //連線service層
    private ManagerBiz managerbiz = (ManagerBiz) BeansContainer.getContext().getBean("managerBiz");
    //例項化翻頁類
    private Paging pa=new Paging();

2、聯合查詢form表單提交到此方法

    /**
     * 購買記錄頁面聯合查詢
     * @param
pa * @param sold * @param model * @param request * @return * @throws ParseException */
@RequestMapping(value="selectSold.action",method=RequestMethod.POST) public String selectSold(Sold sold,HttpServletRequest request) throws ParseException{ System.out.println("聯合查詢"); allPage(sold,request); return "buyRecord"; }

3、點選翻頁(上下頁、首尾頁)時進入此方法

/**
     * 購買記錄頁面翻頁查詢
     * @param currentPage
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value="turnPage.action",method=RequestMethod.GET)
    public String turnPage(Integer currentPage,Integer maxPage,Model model,HttpServletRequest request){
        System.out.println("\r\n翻了個頁");

        Sold sold = (Sold) request.getSession().getAttribute("sold");
        if(currentPage < 1){
            currentPage = 1;
        }
        if(currentPage > maxPage){
            currentPage = maxPage;
        }
        allCount(currentPage,sold,request);

        return "buyRecord";
    }

4、方法體,根據條件查詢需要展示的所有記錄的條數,並計算最大頁數

public void allPage(Sold sold,HttpServletRequest request){
        System.out.println("\r\n模糊查詢記錄總數:" + sold.getUname() + sold.getBeginDate() + sold.getEndDate() );

        int allCount = managerbiz.allCount(sold);

        int maxPage = (allCount/pa.rowsPage);
        if((allCount%pa.rowsPage > 0)){
            maxPage += 1;
        }
        request.getSession().setAttribute("allCount",allCount);
        request.getSession().setAttribute("maxPage",maxPage);

        allCount(1,sold,request);
    }

5、主要查詢方法,獲得list集合反饋給頁面

/**
     * 出售記錄查詢方法體
     * @param sold
     * @param pa
     * @param model
     */
    public void allCount(Integer currentPage,Sold sold,HttpServletRequest request){
        System.out.println("模糊查詢出售記錄:" + currentPage + sold.getUname() + sold.getBeginDate() + sold.getEndDate());

        //計算開始頁與每頁顯示條數
        pa.getPage(currentPage,sold);

        List<Sold> li = managerbiz.selectSold(sold);

        request.setAttribute("records", li);
        request.getSession().setAttribute("currentPage", currentPage);
        request.getSession().setAttribute("sold", sold);

    }

四、service層、dao層與mapper介面

1、service層:
@Service("managerBiz")
public class ManagerBiz {
    //連線dao層
    @Autowired
    private ManagerDao managerdao;

//分頁
    public int allCount(Sold sold){
        return managerdao.allCount(sold);
    }

    public List<Sold> selectSold(Sold sold){
        return managerdao.selectSold(sold);
    }
2、dao層:
@Repository("managerDao")
public class ManagerDao {
    //連線mapper介面
    @Autowired
    private Mapper mapper;

        //分頁
    public int allCount(Sold sold){
        return mapper.allCount(sold);
    }

    public List<Sold> selectSold(Sold sold){
        return mapper.selectSold(sold);
    }
3、mapper介面
public interface Mapper {
    //分頁
    public int allCount(Sold sold);
    public List<Sold> selectSold(Sold sold);
}

五、mapper.xml(mybatis)(關鍵

注:所有表均為mysql
 bs_sold為出售記錄表
 bs_book為書籍表
 bs_user為使用者表
 bs_press為出版社表

1、查詢總內容數量:
<select id="allCount" resultType="int">
    select count(1) from bs_sold s,bs_book b,bs_user u,bs_press p
    where s.bookid = b.id and s.userid = u.id and b.pressid = p.id 
        <if test="uname != null and uname != ''">
            //根據使用者名稱進行模糊查詢
            and u.uname like concat('%',#{uname},'%')
        </if> 
        <if test="beginDate != null">
            and s.time >= #{beginDate}
        </if>
        <if test="endDate != null">
            and #{endDate} >= s.time
        </if>
</select>
2、查詢記錄內容:
<select id="selectSold" resultType="com.bookstore.dto.Sold">
    select s.number,s.price,s.time,s.allprice,u.uname,b.bname,b.author,p.press 
    from bs_sold s,bs_book b,bs_user u,bs_press p
    where s.bookid = b.id and s.userid = u.id and b.pressid = p.id and 
    (select time from bs_sold s,bs_user u where s.userid = u.id
        <if test="uname != null and uname != ''">
            and u.uname like concat('%',#{uname},'%')
        </if> 
        <if test="beginDate != null">
            and s.time >= #{beginDate}
        </if>
        <if test="endDate != null">
            and #{endDate} >= s.time
        </if>
        //order by為排序
        order by s.time desc
        //limit為mysql分頁方法
        limit #{startPage},1
    ) >= s.time 
        order by s.time desc
        limit #{endPage}
</select>
3、mysql的limit分頁方法:
limit x,y
x:查詢記錄開始位置,
y:查詢記錄數量,1便是僅查詢一條資料,
limit查詢從0開始計算

limit x 方法等同於 limit 0,x

①、普通查詢方案:
劣勢:查詢速度較慢
//從第十一條記錄開始查詢,總共查詢十條
select * from book limit 10,10
②、優化方案:
優勢:查詢速度快
//從第十一條記錄開始查詢,總共查十條
select * from 
    (select * from book limit 10,1)
    limit 10

總了個結:
思考分頁的寫法還是非常有趣的,主要是分頁的邏輯理順,會好寫很多。
感覺還有很多很好的方法,求各位大佬指點。