SSM实现后台分页逻辑+前端实现代码

1.提取出分页的逻辑放在工具类中

分页逻辑中需要的属性

  • 1.totalRows:声明数据库中一共有多少条记录,读取数据库时可以获得
  • 2.totalPages:一共能分多少页,通过数据库中有多少条记录和每页显示多少条记录计算出来
    ①如果
      总页数%每页显示的条数==0
        一共能分多少页=总页数/每页显示的条数
    即:totalPages=totalRows/pageSize
    ②如果
      总页数%每页显示的条数!=0
        一共能分多少页=总页数/每页显示的条数+1
    即:totalPages=totalRows/pageSize+1
  • 3.pageSize:每页显示多少条记录,通过前端获取到
  • 4.currentpage:当前是第几页,通过前端获取到。前端是第几页,后端就是第几页
  • 5.start:每页开始的位置。通过当前页和每页显示几条数据计算出来

start?    currentPage(当前页)   pageSize(每页显示几条数据)
0       1             5
5        2             5
10       3               5

start = (currentPage-1)*pageSize

  • 6.end:每页结束的位置,start+pageSize

分页逻辑中需要的方法

  • 1.构造方法(计算一共能分出多少页)

       //构造方法
          public PageInfo(int totalRows,int pageSize){
              this.totalRows=totalRows;
              this.pageSize=pageSize;
      
              //一共能分出多少页
              if (this.totalRows%this.pageSize==0){
                  this.totalPages=this.totalRows/this.pageSize;
              }else {
                  this.totalPages=this.totalRows/this.pageSize+1;
              }
          }
    
  • 2.分页方法

      //分页逻辑
          public void doPaging(int reqPage){
              this.currentPage=reqPage;
              //计算开始和结束的位置
              this.start= (this.currentPage-1)*this.pageSize;
          }
    

完整的分页逻辑代码

	package com.neusoft.util;


	/*
	* 分页信息类
	* @Author
	* @Date 2021-8-16
	* */
	
	import com.neusoft.pojo.Food;
	
	import java.util.List;
	
	public class PageInfo<T> {
	
	    private int totalRows;//声明数据库中一共有多少条记录
	
	    private int totalPages;//一共能分多少页
	
	    private int pageSize;//每页显示多少条记录
	
	    private int currentPage = 1;//当前页,前端是第几页,后端就是第几页。需要接收前端数据

    private int start;//每页开始的位置

    private int end;//每页结束的位置

    private List<T> list; //每页展示所需展示的数据

    //构造方法
    public PageInfo(int totalRows,int pageSize){
        this.totalRows=totalRows;
        this.pageSize=pageSize;

        //一共能分出多少页
        if (this.totalRows%this.pageSize==0){
            this.totalPages=this.totalRows/this.pageSize;
        }else {
            this.totalPages=this.totalRows/this.pageSize+1;
        }
    }

    //分页逻辑
    public void doPaging(int reqPage){
        this.currentPage=reqPage;
        //计算开始的位置
        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.将分页的逻辑在业务逻辑层实现(即在service层实现)

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:当前是第几页
    * pageSize:每页显示多少条记录
    * 通过list.size获取数据库中总的数据条数
    * */

    @Override
    public PageInfo<Food> foodListBiz(int currPage,int pageSize) {
        //1.调用数据库的全表查询,存储在缓存中
        List<Food> list = foodMapper.foodlist();

        //2.调用分页
        PageInfo<Food> pageInfo = new PageInfo<Food>(list.size(),pageSize);

        //3.开始分页
        pageInfo.doPaging(currPage);

        //设置每一页的最后一条数据
        //如果当前页为最后一页
        if (currPage==pageInfo.getTotalPages()){
            //最后一条数据==总数据的长度
            pageInfo.setEnd(list.size());
        }
        //
        else {
            pageInfo.setEnd(pageInfo.getStart() + pageSize);

        }
        
//        sublist为分页结果[start,end)
        List<Food> sublist = list.subList(pageInfo.getStart(),pageInfo.getEnd());

       //5.将分页结果存到pageInfo中的list
        pageInfo.setList(sublist);

        return pageInfo;
    }
}

3.controller层实现分页

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 {

//    通过@Autowired让spring实现bean的自动装配工作
    @Autowired
    IFoodService foodService;

    @ResponseBody
    @RequestMapping("/list")
    
    /*
    * currPage:为前端传过来的当前页
    * PageSize:为前端传过来的每页显示的数据条数
    * */
    public PageInfo<Food> listfoods(int currPage, int pageSize)
    {
        return foodService.foodListBiz(currPage,pageSize);
    }
}

4.通过拦截器,实现将数据从数据库中加载到缓存

目的:是为了让分页逻辑更高效。我们要把数据库中的所有数据加载到缓存中,这样可以大幅缩短请求耗时(因为只有第一个用户是从数据库中拿数据,同时数据被加载到缓存中,请求耗时稍微长一点。其余用户直接从缓存中拿数据,请求耗时很短)
实现方式:

拦截器代码:

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
//    请求发生前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        request.setAttribute("startTime",System.currentTimeMillis());
        System.out.println("请求开始了");
        return true;
    }

    @Override
//    请求完成后
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("请求结束了");
        long startTime=(Long)request.getAttribute("startTime");
        long endTime=System.currentTimeMillis();
        System.out.println("本次请求耗时:"+(endTime-startTime));
    }

    @Override

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

    }
}

mybatis.xml代码

<?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>
        <!--二级缓存总开关-->
        <setting name="cacheEnabled" value="true" />
    </settings>
</configuration>

在application.xml的sqlSessionFactory中配置mybatis.xml对象的别名

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

在这里插入图片描述

  • application.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">
          <!-- 引入db配置文件  -->
          <!-- 配置dataSource数据源 -->
          <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>
          <!-- 创建SqlSessionFactory,并配置实体对象别名 -->
          <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>
      
      
      
          <!-- 配置Mapper。自动扫描Mapper接口,并为其注入SqlSessionFactory -->
          <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
              <property name="basePackage" value="com.neusoft.mapper"></property>
          </bean>
          <!-- 配置Spring提供的事务管理器 -->
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          <!-- 开启注解事务 -->
          <tx:annotation-driven transaction-manager="transactionManager"/>
      
      
      
      </beans>
    

springMVC.xml的配置

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

在这里插入图片描述

  • springMVC.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实现前端分页逻辑

使用element-ui的

<template>
		<div>
			<el-table
			      :data="food"
			      style="width: 100%">
			      <el-table-column
			        prop="foodId"
			        label="食品id"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodName"
			        label="食品名称"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodExplain"
			        label="食品介绍">
			      </el-table-column>
				  <el-table-column
				    prop="foodImg"
				    label="食品图片"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="foodPrice"
				    label="食品价格"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="businessId"
				    label="商家id"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="remarks"
				    label="备注"
				   >
				  </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{
				// 一共有多少条数据
				total:0,
				//每页显示条数
				pageSize:2,
				//当前页
				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)
					})
			},
			// 每页条数改变时触发
			handleSizeChange(pageSize) {
			        console.log(pageSize+"条每页");
					this.pageSize=pageSize
					this.handleCurrentChange(this.currentPage)
			      },
			handleCurrentChange(currentPage) {
			        console.log("当前为:"+currentPage+"页");
					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>

自己定义的

<template>
		<div>
			<el-table
			      :data="food"
			      style="width: 100%">
			      <el-table-column
			        prop="foodId"
			        label="食品id"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodName"
			        label="食品名称"
			       >
			      </el-table-column>
			      <el-table-column
			        prop="foodExplain"
			        label="食品介绍">
			      </el-table-column>
				  <el-table-column
				    prop="foodImg"
				    label="食品图片"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="foodPrice"
				    label="食品价格"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="businessId"
				    label="商家id"
				   >
				  </el-table-column>
				  <el-table-column
				    prop="remarks"
				    label="备注"
				   >
				  </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{
				// 一共有多少页
				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>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值