1. 程式人生 > >SSM框架手動實現分頁邏輯(非PageHelper)

SSM框架手動實現分頁邏輯(非PageHelper)

第一種方法:查詢出所有資料再分頁

分析:

  1. 分頁時,需要獲得前臺傳來的兩個引數,分別為pageNo(第幾頁資料),pageSize(每頁的條數);
  2. 根據這兩個引數來計算出前端需要的資料是查出資料list中的開始索引和結束索引;
  3. 利用List 的subList方法來分割查詢出來的所有資料並返回;

實現過程

1. 獲取引數

這裡返回的是json資料介面,實現方法在service層

@ResponseBody
@GetMapping("/allPage")
public String findAllPage(
   @RequestParam(required = true,defaultValue = "1") Integer pageNo,
   @RequestParam(required = false,defaultValue = "5") Integer pageSize) {
    return customerService.findAllPage(pageNo,pageSize);
}

2. 擷取資料

CustomerServiceImpl.java

  • 裡面的pageUtil類,iterCustomer()方法,JsonUtil類在下面有所介紹,抽離這些類或者方法的目的是提高程式碼的複用性,減少程式碼冗餘;
@Override
public String findAllPage(Integer pageNo, Integer pageSize) {
    List<Customer> customers = customerDao.findAll();
    List<Map<String, String>> resultList = new ArrayList<>();
    PageUtil<Customer> pageUtil = new PageUtil<>();
    for (Customer customer : pageUtil.pageList(customers, pageNo, pageSize){
        resultList.add(iterCustomer(customer));
    }
    return JsonUtil.toJSON(resultList);
}

==PageUtil.java==

  • 這個類是我抽取出來的一個擷取List的工具類,建立物件時需要傳一個泛型,型別為處理列表List中的型別;
  • 該類物件呼叫pageList方法即可返回一個擷取好長度的List 陣列;
  • pageList方法有三個引數,
    • 第一個引數為儲存所有資料的List陣列;
    • 第二個引數為頁碼;
    • 第三個引數為每一頁顯示的資料條數;
public class PageUtil<T> {
    private int beginIndex;//起始索引
    private int endIndex;//終止索引

    public List<T> pageList(List<T> list, int pageNo, int pageSize) {
        int size = list.size();

        beginIndex = (pageNo - 1) * pageSize;
        endIndex = pageNo * pageSize > size ? size : pageNo * pageSize;
        List<T> resultList = list.subList(beginIndex, endIndex);
        return resultList;
    }
}

iterCustomer()方法

  • 作用是得到一個map儲存一個Customer例項的值,用鍵值對錶示;
  • 引數為需要包裝的類物件;
  • 返回值為一個Map物件,裡面儲存了引數類物件的一些資訊;
public Map<String, String> iterCustomer(Customer customer) {
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("id", customer.getId().toString());
        resultMap.put("name", customer.getName());
        resultMap.put("phone", customer.getPhone());
        resultMap.put("email", customer.getEmail());
        return resultMap;
}

JsonUtil.java

  • 作用是封裝Jackson,返回一個json字串;
public class JsonUtil {
    //使用jackson 轉換 json 資料的第一步
    private static ObjectMapper MAPPER = new ObjectMapper();
    static String jsonString=null;

    public static String toJSON(Object object){
        try {
            //jackson轉任意object物件 為json 字串 
            jsonString = MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonString;
    }
}

第二種方法:用SQL分頁,只查詢當前頁所需要的資料

分析:

  • 第一種方法在資料量比較小時可以使用,但當資料量非常大時,如果我們僅需要某一頁的幾條資料,而去查詢所有資料,顯得沒有必要,或者說代價太大,所有我們現在採用第二種分頁方式;

  • 第二種方法與第一種類似,獲取前端傳來的頁碼和每頁顯示的條數,通過自定義SQL語句查詢資料庫來得到需要的資料;

  • sql分頁參考:

    Mysql複雜查詢 或

    【MySQL】條件查詢之排序聚合分組分頁查詢

實現過程

1. 獲取引數

分析

  • 引數中,pageNo是前端傳來的頁碼,即第幾頁;pageSize是每一頁要顯示的條數,預設為5;
  • 使用SQL分頁時,查詢語句中需要的引數為顯示資料在資料庫中的索引和每頁顯示的資料條目數;
    • 計算索引的公式:開始的索引 = (當前的頁碼 - 1) * 每頁顯示的條數;
  • 在這裡還要判斷一下前端傳來的頁碼數是否超出總資料最大的分頁數,如果超出則顯示最大頁數;
    • 最大頁數計算:int maxPage =(int) Math.ceil(count/pageSize.doubleValue());

CustomerController.java

@Controller
public class CustomerController {
    @Autowired
    CustomerService customerService;
    
    @ResponseBody
    @GetMapping("/allSql")
    public String findAllPageSql(
        @RequestParam(required = true,defaultValue = "1") Integer pageNo,
        @RequestParam(required = false,defaultValue = "5") Integer pageSize) {
         /**
         * pageSize 是每頁顯示的條數
         * pageNo 是頁碼,sql分頁傳遞的第一個引數是開始的索引;
         * 計算公式:開始的索引 = (當前的頁碼 - 1) * 每頁顯示的條數
         */
        //資料總數
        int count = customerService.count();
        //計算最大頁碼
        int maxPage =(int) Math.ceil(count/pageSize.doubleValue());
        //當前頁碼超出最大頁碼返回最大頁碼值:
        pageNo = pageNo>maxPage?maxPage:pageNo;
        //分頁開始的索引值
        int index = (pageNo - 1) * pageSize > count ? count : (pageNo - 1) * pageSize;
        return customerService.findAllPageSql(index, pageSize);
    }
}

2.分層呼叫方法

CustomerServiceImpl.java

@Service
public class CustomerServiceImpl implements CustomerService {
    @Autowired
    CustomerDao customerDao;
    @Override
    public String findAllPageSql(Integer index, Integer pageSize) {
        return JsonUtil.toJSON(customerDao.findAllPageSql(index, pageSize));
    }
}

CustomerDao.java

public interface CustomerDao {   
    List<Customer> findAllPageSql(Integer index,Integer pageSize);
}

3.定製sql

CustomerMapper.xml

  • 注意,這裡引數為兩個,獲取引數時要使用#{param1}#{param2},或者通過封裝Map的形式傳參;

  • sql分頁參考:

    Mysql複雜查詢 或

    【MySQL】條件查詢之排序聚合分組分頁查詢

<?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.vue.dao.CustomerDao">
    <select id="findAllPageSql" parameterType="java.lang.Integer" resultType="com.vue.entity.Customer">
        SELECT * FROM t_customer LIMIT #{param1},#{param2}
    </select>
</mapper>

Mapper.xml對映檔案獲取多個引數參考:

Mybatis中的Mapper.xml對映檔案sql查詢接收多個引數 或

Mybatis中的Mapper.xml對映檔案sql查詢接收多個引數


以上

  • 以上就是SSM框架不用PageHelper外掛實現分頁的全過程,推薦使用第二種定製SQL查詢,因為此種查詢方法更加符合分頁邏輯的實現,每次只查詢需要的資料,而不是每次都要查詢所有資料,故效率更高。
  • 有問題可以一起交流: