参考:
https://www.cnblogs.com/xifengxiaoma/p/11027551.html
https://blog.csdn.net/wu1997___/article/details/111478479
注意: 我这里直接使用springboot在线模板创建的,即springboot2.6.0, springboot2.6.0默认情况完全禁止Bean的循环引用,当我们使用依赖注入@Resource和@Autowired时候,直接启动报错,说出现循环依赖等英文。
解决方法:你也可以通过下面的配置,放开不允许循环依赖的要求:
spring.main.allow-circular-references=true
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-mabtis-pagehelper</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mabtis-pagehelper</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--druid-spring-boot-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<!--mybatis-spring-boot-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--pagehelper-spring-boot-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<!--web核心-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--springboot打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
pagehelper.helper-dialect=mysql
pagehelper.params=count=countSql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
或者yml:
server:
port: 8080
spring:
datasource: #数据源连接信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
main: #springboot2.6要开启允许循环依赖
allow-circular-references: true
#mybatis的配置
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.springboot.entity
configuration:
map-underscore-to-camel-case: true
#分页插件的配置
pagehelper:
#配置四項 hprs
helper-dialect: mysql #分页助手方言:mysql
params: count=countSql #为了支持 startPage(Object params) 方法
support-methods-arguments: true #支持通过 Mapper 接口参数来传递分页参数,默认值 false
reasonable: true #分页合理化参数,默认值为 false,页码不为负,不超总页码
logging: #打印sql拼接语句日志
level:
root: debug
配置参数说明:
首先,在 DAO 层添加一个分页查找方法。这个查询方法跟查询全部数据的方法(除了名称)几乎一样。
package com.example.springboot.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String bookName;
private String bookAuthor;
private Double bookMoney;
public Book(String bookName, String bookAuthor, Double bookMoney) {
this.bookName = bookName;
this.bookAuthor = bookAuthor;
this.bookMoney = bookMoney;
}
}
分页的返回值是List:
package com.example.springboot.dao;
import com.example.springboot.entity.Book;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper //此注解可以加,也可以不加,因为我们在主启动类加了@MapperScan
@Repository //dao层的注解
public interface BookMaper {
//分页查询所有
public List<Book> selectAllByPage();
//动态条件查询加分页
public List<Book> selectByPageAndCondition(Book book);
}
然后在 BookDao.xml 中加入selectPage的实现,当然你也可以直接用@Select注解将查询语句直接写在DAO代码,但我们这里选择写在XML映射文件,这是一个普通的查找全部记录的查询语句,并不需要写分页SQL,分页插件会拦截查询请求,并读取前台传来的分页查询参数重新生成分页查询语句。
注意:selectAllByPage这个sql语句最后不能加分号,因为要拼接limit语句的。
BookDao.xml:
<?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">
<!--namespace对应mapper接口所在的位置-->
<mapper namespace="com.example.springboot.dao.BookDao">
<resultMap id="BaseResultMap" type="com.example.springboot.entity.Book">
<id column="id" property="id" jdbcType="INTEGER"></id>
<result column="book_name" property="bookName" jdbcType="VARCHAR"></result>
<result column="book_author" property="bookAuthor" jdbcType="VARCHAR"></result>
<result column="book_money" property="bookMoney" jdbcType="DOUBLE"></result>
</resultMap>
<sql id="BaseColumn">id,book_name,book_author,book_money </sql>
<!--public List<Book> selectAllByPage();-->
<select id="selectAllByPage" resultMap="BaseResultMap">
select <include refid="BaseColumn"></include>
from t_book
</select>
<!--public List<Book> selectByPageAndCondition(Book book);-->
<select id="selectByPageAndCondition" parameterType="book" resultMap="BaseResultMap">
select <include refid="BaseColumn"></include>
from t_book
<where>
<if test="id!=null and id!='' ">id = #{id}</if>
<if test="bookName!=null and bookName!='' ">
<bind name="bookName" value=" '%'+bookName+'%' "/>
and book_Name like #{bookName}</if>
<if test="bookAuthor!=null and bookAuthor!='' ">
<bind name="bookAuthor" value=" '%'+bookAuthor+'%' "/>
and book_author like #{bookAuthor}</if>
<if test="bookMoney!=null and bookMoney!='' ">and book_money = #{bookMoney}</if>
</where>
</select>
</mapper>
服务层通过调用DAO层代码完成分页查询,这里统一封装分页查询的请求和结果类,从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会影响服务层以上的分页接口,起到了解耦的作用。
我们使用官方的PageInfo对结果进行包装,这样就不需要我们自己写一个封装分页结果的类了:
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum());
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());
PageInfo中每个参数代表的意思 示例:
pageNum=1,当前页码
pageSize=1,每页个数
size=1,当前页个数
startRow=1,由第几条开始
endRow=1,到第几条结束
total=3,总条数
pages=3,总页数
list= XXXX 查出出来的数据集合
prePage=0,上一页
nextPage=2,下一页
isFirstPage=true,是否为首页
isLastPage=false,是否为尾页
hasPreviousPage=false,是否有上一页
hasNextPage=true,是否有下一页
navigatePages=8,每页显示的页码个数
navigateFirstPage=1,首页
navigateLastPage=3,尾页
navigatepageNums=[1, 2, 3]}页码数
由于pageHelper插件内置了 分页PageBean对象 : PageInfo,所以,这里使用主要有以下几个步骤:
1> 在service层进行分页
2> 设置分页参数 : PageHelper.startPage(page,size),其中page为当前页,size为每页显示条数
3> 调用dao层的查询全部方法 : PageHelper插件会自动的对下边第一个查询方法进行分页
4> 封装返回值PageInfo;
分页的所有逻辑在这一层完成,包括分页信息的封装,参数传递等:
service接口:方法返回值为PageInfo:
package com.example.springboot.service;
import com.example.springboot.entity.Book;
import com.github.pagehelper.PageInfo;
public interface BookService {
/**
* 分页查询接口
* 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象
* 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会
* 影响服务层以上的分页接口,起到了解耦的作用
* 返回值:PageInfo(官方封装好的分页返回信息类)
*/
//分页参数这里必须带(因为前端一定会传递分页的两个参数的),分页的本质就是在server层进行包装和执行
public PageInfo<Book> selectAllByPageInfo(Integer pageNum, Integer pageSize);
//动态条件查询加分页
public PageInfo<Book> selectByPageAndCondition(Integer pageNum, Integer pageSize,Book book);
}
service实现类:分页方法的返回值也是PageInfo:
package com.example.springboot.service.impl;
import com.example.springboot.dao.BookDao;
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookserviceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public PageInfo<Book> selectAllByPageInfo(Integer pageNum, Integer pageSize) {
//1.分页的开始页的分页设置,分页一定要至少传递这两个参数
PageHelper.startPage(pageNum, pageSize);
//2.紧跟分页设置的后的第一个select查询会被分页查询
List<Book> books = bookDao.selectAllByPage();
//3.PageInfo参数navigatepage(导航页,显示的页码):默认显示5个连续页,页码导航连续显示的页数5
PageInfo<Book> bookPageInfo = new PageInfo<Book>(books,5);
return bookPageInfo;
}
@Override
public PageInfo<Book> selectByPageAndCondition
(Integer pageNum, Integer pageSize, Book book) {
//1.分页助手开始分页
PageHelper.startPage(pageNum,pageSize);
//2.调用dao层的select查询方法,第一个select方法会被分页
List<Book> books = bookMaper.selectByPageAndCondition(book);
//3。封装分页结果到PageInfo中
PageInfo<Book> bookPageInfo = new PageInfo<>(books, 5);
return bookPageInfo;
}
}
package com.example.springboot.controller;
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping(value = "/selectAllByPage" ,method = RequestMethod.GET)
public PageInfo<Book> selectAllByPage(
@RequestParam(required = true,defaultValue = "1",value ="pageNum" )Integer pageNum,
@RequestParam(required = false,defaultValue = "5",value = "pageSize")Integer pageSize){
if(pageNum==null){
pageNum=1;
}
if(pageSize==null){
pageSize=10;
}
PageInfo<Book> pageInfo = bookService.selectAllByPageInfo(pageNum, pageSize);
return pageInfo;
}
@ResponseBody //动态查询的分页
@RequestMapping(value = "/selectByPageAndCondition",method = RequestMethod.GET)
public PageInfo<Book> selectByPageAndCondition(
@RequestParam(value = "pageNum",required = true,defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize",required = false,defaultValue = "5") Integer pageSize,
Book book){
PageInfo<Book> bookPageInfo = bookService.selectByPageAndCondition(pageNum, pageSize, book);
return bookPageInfo;
}
}
数据库数据展示:
动态条件加分页的postman测试:
使用pageHelper插件来分页,只需在执行sql前用即可
String orderBy = 排序字段 + ” desc”;//按照(数据库)排序字段 倒序 排序
PageHelper.startPage(pageNum, pageSize, orderBy)
或者: service实现类:
@Override
public PageInfo<Book> selectByPageAndCondition
(Integer pageNum, Integer pageSize,String orderBy, Book book) {
//1.分页助手开始分页
PageHelper.startPage(pageNum,pageSize);
PageHelper.orderBy(orderBy); //排序的方法 PageHelper.orderBy(String orderBy)
//2.调用dao层的select查询方法,第一个select方法会被分页
List<Book> books = bookMaper.selectByPageAndCondition(book);
//3。封装分页结果到PageInfo中
PageInfo<Book> bookPageInfo = new PageInfo<>(books, 5);
return bookPageInfo;
}
controller:
@ResponseBody //动态查询的分页
@RequestMapping(value = "/selectByPageAndCondition",method = RequestMethod.GET)
public PageInfo<Book> selectByPageAndCondition(
@RequestParam(value = "pageNum",required = true,defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize",required = false,defaultValue = "5") Integer pageSize,
@RequestParam(value = "orderBy",required = false) String orderBy,
Book book){
PageInfo<Book> bookPageInfo =
bookService.selectByPageAndCondition(pageNum, pageSize,orderBy, book);
return bookPageInfo;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179534.html原文链接:https://javaforall.cn