提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
1.分页查询概述
- 常规查询全部出现的风险 : 分页查询将数据库中庞大的数据分段显示,每页显示用户自定义的行数,提高用户体验度,最主要的是如果一次性从服务器磁盘中读出全部数据到内存,有内存溢出的风险。
- 后端分页与前端分页的最大不同就是,它不需要一次性向后端请求大量的数据,而是根据用户的设定,一次请求一定量的数据,然后将这些数据回显到页面上,后端分页也才是分页的正确打开方式,其避免了一次性从数据库获取很多数据,也可以美化前端展示效果,优化用户体验。
- 在开发过程中,我们经常会从数据库中查询数据,然后在客户端显示出来。当数据少时,可以在一个页面显示。当我们查询几百条以上数据,直接显示在一个页面上,不仅浏览不方便,查询效率也会受到影响,这是,我们就可以使用分页查询来解决这个问题。
- 基本分页查询思路
- 我现阶段的分页查询的实现是基于sql语句的。
select * from user where id limit a, b
- 构造出相应的a和b就可以查询出想要的数据,在显示在页面上。重点是要构造出当前的页数,就要封装一个javaBean,存储有关分页的基本属性。
- 这样只需在service层计算想要的页数,并封装基本的信息,在查询出来显示在前端就可以了。
2.原始的JDBC实现分页查询步骤
2.1 需求
- 在后端项目中总是避免不了admin管理,当后台管理需要展示数据时就会需要用到分页,接下来通过分页查询的方式,来查询学生信息
2.2导入相关jar包/Maven依赖
<dependencies>
<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<!--Lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
2.2 创建实体类(pojo)
学生实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Integer age;
}
分页实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageInfo<T> {
private Long currentPage;//当前页数
private Integer pageSize;//每页记录数
private Long totalSize;//总记录数
private Long totalPage;//总页数
private List<T> data;//当前页数据
}
2.3 创建数据库配置信息druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydb1
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
2.4 创建JDBCUtils.java工具类
public class JDBCUtils {
private static DataSource dataSource;
static {
Properties properties = new Properties();
try {
properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
} catch (IOException e) {
e.printStackTrace();
}
try {
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void release(Connection connection, Statement statement, ResultSet resultSet) {
if (null != connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
connection = null;
}
if (null != statement) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
resultSet = null;
}
}
public static void release(Connection connection, Statement statement) {
release(connection, statement, null);
}
}
2.5 编写Dao(持久)层代码
编写DemoDao接口
该接口有两个功能,一个是分页查询数据,另一个是查询总记录数
public interface DemoDao {
/**
* 分页查询
* @param begin 起始查找的位置
* @param pageSize 要查找的数量
* @return
*/
public List<Student> findPage(Long begin,Integer pageSize);
/**
* 查询总记录数
* @return
*/
public Long getTotalSize();
}
编写DemoDao的实现类,DemoDaoImpl.java
public class DemoDaoImpl implements DemoDao {
/**
* 分页查询
* @param begin 起始查找的位置
* @param pageSize 要查找的数量
* @return
*/
public List<Student> findPage(Long begin, Integer pageSize) {
Connection connection = null;
try {
// 1.连接数据库
connection = JDBCUtils.getConnection();
// 2.创建查询语句
QueryRunner queryRunner = new QueryRunner();
List<Student> student = queryRunner.query(
connection,
"select * from student limit ?,?",
new BeanListHandler<Student>(Student.class),
begin,
pageSize
);
return student;
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.release(connection, null);
}
return null;
}
/**
* 查询总记录数
* @return
*/
public Long getTotalSize() {
Connection connection = null;
try {
// 创建连接
connection = JDBCUtils.getConnection();
// 查询总记录
return new QueryRunner()
.query(
connection,
"select count(*) from student",
new ScalarHandler<Long>()
);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.release(connection, null);
}
return -1L;
}
}
2.6 编写service(业务)层
编写DemoService接口
public interface DemoService {
/**
* 分页查询
* @param currentPage
* @param pageSize
* @return
*/
public PageInfo<Student> findPage(Long currentPage, Integer pageSize);
}
编写DemoService接口实现类DemoServiceImpl.java
public class DemoServiceImpl implements DemoService {
public PageInfo<Student> findPage(Long currentPage, Integer pageSize) {
DemoDao dao = new DemoDaoImpl();
// 封装数据
PageInfo<Student> pageInfo = new PageInfo<Student>();
// 当前页数
pageInfo.setCurrentPage(currentPage);
// 每页记录数
pageInfo.setPageSize(pageSize);
// 总记录数
Long totalSize = dao.getTotalSize();
pageInfo.setTotalSize(totalSize);
// 总页数
Long totalPage = (totalSize % pageSize == 0 ) ? totalSize / pageSize : totalSize / pageSize + 1;
pageInfo.setTotalPage(totalPage);
// 当前页的数据
Long begin = (currentPage - 1) * pageSize;
List<Student> data = dao.findPage(begin, pageSize);
pageInfo.setData(data);
return pageInfo;
}
}
2.7 编写测试类
public class DemoServiceTest {
@Test
public void findPage() {
DemoService demoService = new DemoServiceImpl();
PageInfo<Student> page = demoService.findPage(1L, 2);
System.out.println("page = " + page);
}
}
3.通过Mybatis插件来实现分页查询步骤
3.1 需求
- 在后端项目中总是避免不了admin管理,当后台管理需要展示数据时就会需要用到分页,接下来通过分页查询的方式,来查询学生信息
3.1 导入相关依赖/jar包
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
3.2 创建实体类(pojo)
Student.java
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {
private Integer id;
private String name;
private Integer age;
}
3.3 编写数据库连接信息配置文件jdbc.properties
url=jdbc:mysql://localhost:3306/mydb1?useSSL=false
username=root
password=root
driver=com.mysql.cj.jdbc.Driver
3.4 编写核心配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
<properties resource="jdbc.properties"></properties>
<!-- 配置核心配置文件 -->
<plugins>
<!--
PageInterceptor : 拦截查询所有的sql语句, 在后面拼接分页查询的sql
-->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--已经在第一页, 点击上一页, 返回第一页数据-->
<property name="reasonable" value="true"/>
<!--不同类型的数据库的分页查询的sql语句不一样-->
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
<!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
<environments default="development">
<!--environment配置数据库环境 id属性唯一标识-->
<environment id="development">
<!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
<transactionManager type="JDBC"/>
<!-- dataSource数据源信息 type属性 连接池-->
<dataSource type="POOLED">
<!-- property获取数据库连接的配置信息 -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--Mapper映射文件-->
<mappers>
<!-- mapper 引入指定的映射配置文件 resource属性指定映射配置文件的名称 -->
<mapper resource="com/batis/dao/StudentDao.xml"/>
</mappers>
</configuration>
3.5 编写映射配置文件StudentDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.batis.dao.StudentDao">
<!--
id:Mapperp中唯一标识
parameterType:输入映射的类型
resultType:输出映射的类型
-->
<select id="findAll" resultType="com.batis.pojo.Student">
select * from student
</select>
</mapper>
3.6 编写Dao(持久)层
编写StudentDao.java
public interface StudentDao {
/**
* 查询所有
* @return
*/
List<Student> findAll();
}
3.7 编写Service(业务)层
编写StudentService接口
public interface StudentService {
PageInfo<Student> findPage(Integer currentPage,Integer pageSize) throws IOException;
}
编写StudentService接口的实现类
public class StudentServiceImpl implements StudentService {
public PageInfo<Student> findPage(Integer currentPage, Integer pageSize) throws IOException {
//开始分页查询 , 触发PageInterceptor
PageHelper.startPage(currentPage,pageSize);
// 查询所有
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List<Student> all = studentDao.findAll();
// 分页查询
return new PageInfo<Student>(all);
}
}
3.8 编写测试类
public class StudentServiceTest {
@Test
public void findPage() throws IOException {
StudentServiceImpl studentService = new StudentServiceImpl();
PageInfo<Student> page = studentService.findPage(1, 2);
System.out.println("page = " + page);
}
}