12. 如何在MyBatis中进行分页查询?常见的分页实现方式有哪些?
在MyBatis中,分页查询是一种常见的需求,尤其是在处理大数据量的情况下。MyBatis本身不直接提供分页功能,但可以通过以下几种常见的实现方式来实现分页查询。
1. 手动分页
这是最基本的分页方式,直接在SQL语句中添加分页参数。不同的数据库分页语法不同,以下是一些常见数据库的分页实现。
1.1 MySQL中的分页
<select id="findUsersByPage" resultType="User">
SELECT * FROM users
LIMIT #{offset}, #{pageSize}
</select>
-
LIMIT #{offset}, #{pageSize}
:offset
表示起始行偏移量,pageSize
表示每页的记录数。
1.2 Oracle中的分页
<select id="findUsersByPage" resultType="User">
SELECT * FROM (
SELECT A.*, ROWNUM AS RN
FROM (SELECT * FROM users ORDER BY id) A
WHERE ROWNUM <= #{endRow}
)
WHERE RN > #{startRow}
</select>
-
Oracle使用ROWNUM来实现分页,其中
startRow
和endRow
分别表示分页的起始和结束行号。
1.3 SQL Server中的分页
<select id="findUsersByPage" resultType="User">
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNum, *
FROM users
) AS result
WHERE RowNum BETWEEN #{startRow} AND #{endRow}
</select>
-
SQL Server中,使用ROW_NUMBER()函数进行分页,并结合
BETWEEN
语句来筛选行号范围。
2. 使用RowBounds对象进行分页
MyBatis提供了RowBounds
对象用于内存分页。它会将查询结果集限制在指定的行数内。这种方式不依赖于数据库的分页语法,而是通过Java内存进行分页。
2.1 使用RowBounds分页
List<User> findUsers(RowBounds rowBounds);
java复制代码RowBounds rowBounds = new RowBounds(offset, pageSize);
List<User> users = userMapper.findUsers(rowBounds);
-
RowBounds
通过offset
和limit
进行分页。
2.2 注意事项
-
RowBounds
会将查询的所有结果集加载到内存中,然后进行分页处理,这对大数据量查询效率较低,适合小数据量分页场景。
3. 使用分页插件
分页插件是一种更为高效和方便的方式,特别是在大型项目中。分页插件会自动拦截查询SQL,并在其基础上增加分页逻辑。
3.1 MyBatis-PageHelper插件
PageHelper
是MyBatis的一个常用分页插件,它通过拦截SQL语句并追加分页语句来实现分页查询。
-
Maven依赖:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>
-
配置方式:
@Configuration public class MyBatisConfig { @Bean public PageHelper pageHelper() { PageHelper pageHelper = new PageHelper(); Properties properties = new Properties(); properties.setProperty("helperDialect", "mysql"); properties.setProperty("reasonable", "true"); properties.setProperty("supportMethodsArguments", "true"); pageHelper.setProperties(properties); return pageHelper; } }
-
使用方式:
PageHelper.startPage(pageNum, pageSize); List<User> users = userMapper.findAll(); PageInfo<User> pageInfo = new PageInfo<>(users);
-
PageHelper.startPage(pageNum, pageSize)
:设置分页参数,pageNum
表示当前页码,pageSize
表示每页显示的记录数。 -
PageInfo<User>
:PageInfo
是一个分页结果对象,包含了分页后的信息,如总页数、总记录数等。
-
3.2 MyBatis-Plus中的分页插件
MyBatis-Plus也提供了分页插件,使用方式类似于PageHelper。
-
Maven依赖:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.4</version> </dependency>
-
配置方式:
@Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
-
使用方式:
Page<User> page = new Page<>(pageNum, pageSize); IPage<User> userPage = userMapper.selectPage(page, null);
-
Page<>(pageNum, pageSize)
:构建分页参数对象。 -
IPage<User>
:MyBatis-Plus中的分页结果对象,包含分页后的数据和分页信息。
-
4. 数据库支持的分页查询
有些数据库(如MySQL、PostgreSQL)天生支持分页查询,可以直接在SQL语句中使用LIMIT
、OFFSET
等关键字进行分页,而其他数据库(如Oracle)则需要使用子查询或窗口函数来实现分页。
总结
在MyBatis中实现分页查询的方式主要有以下几种:
-
手动分页:直接在SQL中编写分页语句,适合于需要控制分页SQL的场景,但需要根据不同数据库编写不同的分页SQL。
-
RowBounds
分页:MyBatis提供的内存分页方法,适合小数据量分页,但不推荐大数据量使用。 -
分页插件:如PageHelper、MyBatis-Plus分页插件,通过拦截器方式实现分页,自动生成分页SQL,适合大多数场景,性能较好。
选择哪种分页方式应根据项目的实际需求、数据量大小以及开发的复杂性进行权衡。对于大多数场景,使用分页插件是一个简单高效的选择。