转载

Spring Boot +MyBatis+ MySQL+Vue实现数据分页操作

 分页,关键字:count, limit, offset

JPA 通常 repository, myBatis 则 mapper 多一些

mongodb, redis, spring data 官方推荐 repository

Java 中一个方法可以返回多个值吗?包装后可以。

数据库:注意:如果数据过多,可以采用

select * from city \G


 

工程目录:


 application.properties

#数据源
spring.datasource.url=jdbc:mysql://阿里云ip:3306/world
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


spring.http.log-request-details=true
logging.level.web=debug

City.java

package com.newer.page.pojo;

//驼峰式命名法
//+-------------+----------+------+-----+---------+----------------+
//| Field       | Type     | Null | Key | Default | Extra          |
//+-------------+----------+------+-----+---------+----------------+
//| ID          | int      | NO   | PRI | NULL    | auto_increment |
//| Name        | char(35) | NO   |     |         |                |
//| CountryCode | char(3)  | NO   | MUL |         |                |
//| District    | char(20) | NO   |     |         |                |
//| Population  | int      | NO   |     | 0       |                |



public class City {

	int id;
	
	String name;
	
	String countryCode;
	
	String district;
	
	int population;
	
	public City() {
		
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCountryCode() {
		return countryCode;
	}

	public void setCountryCode(String countryCode) {
		this.countryCode = countryCode;
	}

	public String getDistrict() {
		return district;
	}

	public void setDistrict(String district) {
		this.district = district;
	}

	public int getPopulation() {
		return population;
	}

	public void setPopulation(int population) {
		this.population = population;
	}

	@Override
	public String toString() {
		return "City [id=" + id + ", name=" + name + ", countryCode=" + countryCode + ", district=" + district
				+ ", population=" + population + "]";
	}
	
	
	
}

CityRepository.java

package com.newer.page.repository;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;


import com.newer.page.pojo.City;

//JPA 通常 repository, myBatis 则 mapper 多一些
/**
 * City的数据访问
 * @author Admin
 *
 */
@Mapper
public interface CityRepository {

	/**
	 * 分页查询
	 *  
	 * @param limit 记录行数
	 * @param offset 偏移量
	 * @return
	 */
//	语句简单
	@Select("select * from city where CountryCode='CHN' order by id limit #{limit} offset #{offset}")
//	用到动态SQL
//	@SelectProvider
	List<City> find(@Param("limit") int limit, @Param("offset")  int offset);
	
	/**
	 * 记录总数
	 * 
	 * @return int 记录总数
	 */
	@Select("select count(id) from city where  CountryCode='CHN'")
	int count();
}

AppService.java

package com.newer.page.service;

import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.newer.page.pojo.City;
import com.newer.page.repository.CityRepository;
import com.newer.page.util.Page;

/**
 * 
 * 业务逻辑:粒度远大于POJO
 * @author Admin
 *
 */
@Service
public class AppService {

	@Autowired
	CityRepository cityRepository;
	
	/**
	 * 
	 * @param page 第几页,从0开始
	 * @param size 一页多少数据
	 * @return
	 */
	public Page<City> cityByPage(int page,int size) {
		
//		10
		
//		总记录数
		int count=cityRepository.count();
		
//		第page+1页的数据
		List<City> list=cityRepository.find(size, size*page );
		
//		向上取整计算出页数
		int total=(int)Math.ceil(Double.valueOf(count)/size);
		
//		
//		HashMap<String,Object> data=new HashMap<>(); 
////		列表数据
//		data.put("list", list);
////		总页数
//		data.put("total", total);
////		当前页码
//		data.put("current", page);
		
		Page<City> cityPage=new Page<>();
		
		cityPage.setData(list);
		cityPage.setTotal(total);
		cityPage.setCurrent(page);
		
		return cityPage;
	}
	
	
	
}

HomeController.java

package com.newer.page.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

//	返回视图
	@GetMapping("/")
	public String home() {
		return "index.html";
	}
	
}

CityController.java

package com.newer.page.controller;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.newer.page.pojo.City;
import com.newer.page.service.AppService;
import com.newer.page.util.Page;

@RestController
@RequestMapping("/api/city")
public class CityController {

	@Autowired
	AppService appService;
	
//	Get/api/city ?p=5&s=20
	/**
	 * 获得分页数据
	 * @param page 页码
	 * @param size 一页的记录数,可选,默认20条数据
	 * @return
	 */
	@GetMapping
	public Page<City> find(
			@RequestParam(name="p",defaultValue = "0") int page,
			@RequestParam(name="s",defaultValue = "20") int size
			){
		
//		控制器调用业务逻辑
		return appService.cityByPage(page, size);
	}
}

Page.java

package com.newer.page.util;

import java.util.List;

/**
 * 一页数据
 * 
 * @author Admin
 *
 */
public class Page<T> {

	/**
	 * 数据
	 */
	List<T> data;
	
	/**
	 * 总页数:基于0的开始到total-1
	 */
	int total;
	
	
	/**
	 * 当前页数:基于0的开始
	 */
	int current;
	
	public Page() {
		
	}

	public List<T> getData() {
		return data;
	}

	public void setData(List<T> data) {
		this.data = data;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public int getCurrent() {
		return current;
	}

	public void setCurrent(int current) {
		this.current = current;
	}
	
	
	
	
	
	
}

index.html

<!doctype html>
<html lang="en">

<head>
    <title>数据分页</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div class="jumbotron jumbotron-fluid">
        <div class="container">
            <h1 class="display-3">数据分页</h1>
            <p class="lead">Vue & Spring Boot &MyBatis& MySQL</p>

        </div>
    </div>
    <div id="app" class="container">
        <!-- 表格 -->
        <table class="table">
            <thead>
                <tr>
                    <th>编号</th>
                    <th>城市</th>
                    <th>国家</th>
                    <th>所在地区</th>
                    <th>人口</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(city, index) in  cityList" :key="index">
                    <td>{{city.id}}</td>
                    <td>{{city.name}}</td>
                    <td>{{city.countryCode}}</td>
                    <td>{{city.district}}</td>
                    <td>{{city.population}}</td>
                </tr>

            </tbody>
        </table>

        <!-- 分页 -->
        <nav aria-label="Page navigation">
            <ul class="pagination justify-content-center">
                <li class="page-item ">
                    <a class="page-link" href="#" aria-label="Previous">
                        <span @click="page(index--)" aria-hidden="true" :class="{active: index===current}"  >上一页</span>

                    </a>
                </li>
                <!-- 默认的样式 -->
                <!-- <li class="page-item active"><a class="page-link" href="#">当前</a></li> -->

               
                <li  v-for="(n, index) in total" :key="index" class="page-item" :class="{active: n-1===current}">
                   
                    <a  @click="page(n-1)" class="page-link" href="#">
                        {{n}}
                    </a>
                </li>
                <li class="page-item">
                    <a class="page-link" href="#" aria-label="Next">
                        <span @click="page(index++)"  aria-hidden="true" :class="{active: index===current}">下一页</span>

                    </a>
                </li>
            </ul>
        </nav>

    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                cityList: [],
                // 总页数
                total: '',
                // 当前页
                current: '',
                index:1
            },
            methods: {
                page: function (num) {

                    axios.get('/api/city', {
                        params: {
                            p: num
                        }
                    })
                        .then(res => {
                            // console.log(res);
                            this.cityList = res.data.data;
                            this.total = res.data.total;
                            this.current = res.data.current;
                        })
                },

                next:function(i){
                    axios.get('/api/city', {
                        params: {
                            p:i
                        }
                    })
                    .then(res => {
                        console.log(res);
                    })
                }
            },
            created() {
                // 本地URL
                let url = '/api/city';
                axios.get(url)
                    .then(res => {
                        console.log(res)
                        this.cityList = res.data.data;
                        this.total = res.data.total;
                        this.current = res.data.current;
                    })
                    .catch(err => {
                        console.error(err);
                    })
            },
        })

    </script>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
</body>

</html>

程序运行,浏览器看效果:

 

 

正文到此结束
本文目录