SSM implementation background paging logic + front-end implementation code

Posted by Blu_Smurf on Wed, 22 Dec 2021 18:50:35 +0100

1. Extract the paging logic and put it in the tool class

Properties required in paging logic

  • 1.totalRows: declare the total number of records in the database, which can be obtained when reading the database
  • 2.totalPages: the total number of pages that can be divided is calculated by the number of records in the database and the number of records displayed on each page
    ① If
      total pages% number of items displayed per page = = 0
         how many pages can be divided = total pages / number of items displayed on each page
    That is: totalPages=totalRows/pageSize
    ② If
      total pages% number of items displayed per page= 0
         total number of pages = total number of pages / number of items displayed on each page + 1
    That is: totalPages=totalRows/pageSize+1
  • 3.pageSize: how many records are displayed on each page and obtained through the front end
  • 4.currentpage: the current page is obtained through the front end. What page is the front end and what page is the back end
  • 5.start: the position at the beginning of each page. Calculated through the current page and several pieces of data displayed on each page

start?   CurrentPage   pageSize (several pieces of data per page)
0       1             5
5        2             5
10       3               5

start = (currentPage-1)*pageSize

  • 6.end: end position of each page, start+pageSize

Methods required in paging logic

  • 1. Construction method (calculate the total number of pages)

       //Construction method
          public PageInfo(int totalRows,int pageSize){
              this.totalRows=totalRows;
              this.pageSize=pageSize;
      
              //How many pages can be divided
              if (this.totalRows%this.pageSize==0){
                  this.totalPages=this.totalRows/this.pageSize;
              }else {
                  this.totalPages=this.totalRows/this.pageSize+1;
              }
          }
    
  • 2. Paging method

      //Paging logic
          public void doPaging(int reqPage){
              this.currentPage=reqPage;
              //Calculate the start and end positions
              this.start= (this.currentPage-1)*this.pageSize;
          }
    

Complete paging logic code

	package com.neusoft.util;


	/*
	* Paging information class
	* @Author
	* @Date 2021-8-16
	* */
	
	import com.neusoft.pojo.Food;
	
	import java.util.List;
	
	public class PageInfo<T> {
	
	    private int totalRows;//Declare the total number of records in the database
	
	    private int totalPages;//How many pages can it be divided into
	
	    private int pageSize;//How many records are displayed per page
	
	    private int currentPage = 1;//For the current page, the front end is the page and the back end is the page. Need to receive front-end data

    private int start;//Position at the beginning of each page

    private int end;//End of each page

    private List<T> list; //Each page displays the required data

    //Construction method
    public PageInfo(int totalRows,int pageSize){
        this.totalRows=totalRows;
        this.pageSize=pageSize;

        //How many pages can be divided
        if (this.totalRows%this.pageSize==0){
            this.totalPages=this.totalRows/this.pageSize;
        }else {
            this.totalPages=this.totalRows/this.pageSize+1;
        }
    }

    //Paging logic
    public void doPaging(int reqPage){
        this.currentPage=reqPage;
        //Start of calculation
        this.start= (this.currentPage-1)*this.pageSize;

    }


    public int getTotalRows() {
        return totalRows;
    }

    public void setTotalRows(int totalRows) {
        this.totalRows = totalRows;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}

2. Implement the paging logic in the business logic layer (i.e. in the service layer)

package com.neusoft.service;

import com.neusoft.mapper.FoodMapper;
import com.neusoft.pojo.Food;
import com.neusoft.util.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FoodService implements IFoodService {

    @Autowired
    FoodMapper foodMapper;

    /*
    * currPage:What page is it now
    * pageSize: How many records are displayed per page
    * Via list Size gets the total number of data entries in the database
    * */

    @Override
    public PageInfo<Food> foodListBiz(int currPage,int pageSize) {
        //1. Call the full table query of the database and store it in the cache
        List<Food> list = foodMapper.foodlist();

        //2. Call paging
        PageInfo<Food> pageInfo = new PageInfo<Food>(list.size(),pageSize);

        //3. Start paging
        pageInfo.doPaging(currPage);

        //Set the last data of each page
        //If the current page is the last
        if (currPage==pageInfo.getTotalPages()){
            //Last data = = length of total data
            pageInfo.setEnd(list.size());
        }
        //
        else {
            pageInfo.setEnd(pageInfo.getStart() + pageSize);

        }
        
//        sublist is the paging result [start, end]
        List<Food> sublist = list.subList(pageInfo.getStart(),pageInfo.getEnd());

       //5. Save the paging results to the list in pageInfo
        pageInfo.setList(sublist);

        return pageInfo;
    }
}

3. The controller layer implements paging

package com.neusoft.controller;


import com.neusoft.pojo.Food;
import com.neusoft.service.IFoodService;
import com.neusoft.util.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/food")
public class FoodController {

//    Let spring realize the automatic assembly of bean s through @ Autowired
    @Autowired
    IFoodService foodService;

    @ResponseBody
    @RequestMapping("/list")
    
    /*
    * currPage: The current page passed from the front end
    * PageSize: The number of data pieces displayed for each page transmitted from the front end
    * */
    public PageInfo<Food> listfoods(int currPage, int pageSize)
    {
        return foodService.foodListBiz(currPage,pageSize);
    }
}

4. Load the data from the database to the cache through the interceptor

Purpose: to make paging logic more efficient. We need to load all the data in the database into the cache, which can greatly reduce the request time (because only the first user takes data from the database and the data is loaded into the cache, the request time is a little longer. Other users directly take data from the cache, and the request time is very short)

Implementation method:

Interceptor Code:

package com.neusoft.util;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInter implements HandlerInterceptor {

    @Override
//    Before request
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        request.setAttribute("startTime",System.currentTimeMillis());
        System.out.println("The request began");
        return true;
    }

    @Override
//    After the request is completed
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("The request is over");
        long startTime=(Long)request.getAttribute("startTime");
        long endTime=System.currentTimeMillis();
        System.out.println("This request takes:"+(endTime-startTime));
    }

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

mybatis.xml code

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!--L2 cache master switch-->
        <setting name="cacheEnabled" value="true" />
    </settings>
</configuration>

In application Configure mybatis.xml in sqlSessionFactory Alias of XML object

    <property name="configLocation" value="classpath:mybatis.xml"/>

  • application. Complete code of XML:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans
              xmlns="http://www.springframework.org/schema/beans"
              xmlns:context="http://www.springframework.org/schema/context"
              xmlns:tx="http://www.springframework.org/schema/tx"
              xmlns:aop="http://www.springframework.org/schema/aop"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
                              http://www.springframework.org/schema/context
                              http://www.springframework.org/schema/context/spring-context.xsd
                              http://www.springframework.org/schema/tx
                              http://www.springframework.org/schema/tx/spring-tx.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop.xsd">
          <!-- introduce db configuration file  -->
          <!-- to configure dataSource data source -->
          <bean id="dataSource"
                class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
              <property name="url" value="jdbc:mysql://localhost:3306/business?serverTimezone=UTC&amp;characterEncoding=utf8"></property>
              <property name="username" value="root"></property>
              <property name="password" value="root"></property>
          </bean>
          <!-- establish SqlSessionFactory,And configure the entity object alias -->
          <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"></property>
              <property name="typeAliasesPackage" value="com.neusoft.pojo" />
              <property name="mapperLocations"     value="classpath:mapper/FoodMapper.xml"/>
              <property name="configLocation" value="classpath:mybatis.xml"/>
          </bean>
      
      
      
          <!-- to configure Mapper. Automatic scanning Mapper Interface and inject SqlSessionFactory -->
          <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
              <property name="basePackage" value="com.neusoft.mapper"></property>
          </bean>
          <!-- to configure Spring Provided transaction manager -->
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          <!-- Open annotation transaction -->
          <tx:annotation-driven transaction-manager="transactionManager"/>
      
      
      
      </beans>
    

springMVC.xml configuration

 <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.neusoft.util.MyInter"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

  • springMVC. Complete code of XML

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans.xsd
                              http://www.springframework.org/schema/context
                              http://www.springframework.org/schema/context/spring-context.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop.xsd
                              http://www.springframework.org/schema/mvc
                              http://www.springframework.org/schema/mvc/spring-mvc.xsd">
          <mvc:annotation-driven />
          <context:component-scan base-package="com.neusoft.controller" />
          <context:component-scan base-package="com.neusoft.service"/>
      
      
          <mvc:interceptors>
              <mvc:interceptor>
                  <mvc:mapping path="/**"/>
                  <bean class="com.neusoft.util.MyInter"></bean>
              </mvc:interceptor>
          </mvc:interceptors>
      
      </beans>
    

5.vue implements front-end paging logic

Using element UI

<template>
		<div>
			<el-table
			      :data="food"
			      style="width: 100%">
			      <el-table-column
			        prop="foodId"
			        label="food id"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodName"
			        label="Food name"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodExplain"
			        label="Food introduction">
			      </el-table-column>
				  <el-table-column
				    prop="foodImg"
				    label="Food pictures"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="foodPrice"
				    label="Food price"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="businessId"
				    label="business id"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="remarks"
				    label="remarks"
				   >
				  </el-table-column>
			    </el-table>
				<div class="block">
				    <el-pagination
				      @size-change="handleSizeChange"
				      @current-change="handleCurrentChange"
				      :current-page="currentPage"
				      :page-sizes="[2, 3, 4]"
				      :page-size="pageSize"
				      layout="total, sizes, prev, pager, next, jumper"
				      :total="total">
				    </el-pagination>
				  </div>
		</div>
		
</template>

<script>
	export default{
		data(){
			return{
				// How many pieces of data are there
				total:0,
				//Number of displays per page
				pageSize:2,
				//Current page
				currentPage:1,
				food:[]
			}
		},
		methods:{
			xmlRequestFun(currPage,pageSize){
					let that = this
					this.$axios({
						method:'get',
						url:'http://localhost:8888/proSSM/food/list?currPage='+currPage+'&pageSize='+that.pageSize
					}).then(function(response){
						console.log(response.data)
						console.log(typeof response.data)
						that.total=response.data.totalRows
						that.currentPage=response.data.currentPage
						that.food=response.data.list
						// console.log(typeof that.food)
						console.log(that.total)
					})
			},
			// Triggered when the number of entries per page changes
			handleSizeChange(pageSize) {
			        console.log(pageSize+"Article per page");
					this.pageSize=pageSize
					this.handleCurrentChange(this.currentPage)
			      },
			handleCurrentChange(currentPage) {
			        console.log("Currently:"+currentPage+"page");
					this.currentPage=currentPage
					this.pageFun(this.currentPage)
			      },
			pageFun(pageIndex){
				this.xmlRequestFun(pageIndex,this.pageSize)
				console.log(pageIndex)
			}	
		},
		created() {
			
			this.xmlRequestFun(1,this.pageSize)
		}
	}
</script>

<style>
</style>

Self defined

<template>
		<div>
			<el-table
			      :data="food"
			      style="width: 100%">
			      <el-table-column
			        prop="foodId"
			        label="food id"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodName"
			        label="Food name"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodExplain"
			        label="Food introduction">
			      </el-table-column>
				  <el-table-column
				    prop="foodImg"
				    label="Food pictures"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="foodPrice"
				    label="Food price"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="businessId"
				    label="business id"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="remarks"
				    label="remarks"
				   >
				  </el-table-column>
			    </el-table>
				<p align="right">
					<el-button @click="pageFun(currentPage-1<=0?1:currentPage-1)"><</el-button>
					<el-button @click="pageFun(i)" v-for="i in totalPages">
						{{i}}
					</el-button >
					<el-button @click="pageFun(currentPage+1>totalPages?totalPages:currentPage+1)">></el-button>
				</p>
		</div>
		
</template>

<script>
	export default{
		data(){
			return{
				// How many pages are there altogether
				totalPages:0,
				sizes:0,
				pageSize:3,
				currentPage:1,
				food:[]
			}
		},
		methods:{
			
			
			xmlRequestFun(currPage,pageSize){
					let that = this
					this.$axios({
						method:'get',
						url:'http://localhost:8888/proSSM/food/list?currPage='+currPage+'&pageSize='+that.pageSize
					}).then(function(response){
						console.log(response.data.list)
						console.log(typeof response.data)
						that.totalPages=response.data.totalPages
						that.currentPage=response.data.currentPage
						that.food=response.data.list
						// console.log(typeof that.food)
					})
			},
			pageFun(pageIndex){
				this.xmlRequestFun(pageIndex,this.pageSize)
				console.log(pageIndex)
			}	
		},
		created() {
			this.xmlRequestFun(1,this.pageSize)
		}
	}
</script>

<style>
</style>

Topics: SSM