1. 使用 MyBatis 进行分页
1.1 使用 MyBatis 的 RowBounds
RowBounds 是 MyBatis 提供的一个简单分页工具类,可以在 SQL 执行时传入分页参数。
1. 创建实体类
假如我们有一个 User 实体类
public class User {
private Long id;
private String name;
private Integer age;
// Getters and Setters
}
2. 创建 Mapper 接口
定义一个 Mapper 接口,其中包含查询方法。
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
List<User> selectAllUsers();
}
3. 配置 MyBatis
确保 MyBatis 配置文件中正确配置了 Mapper 接口。
<mappers>
<mapper class="com.example.mapper.UserMapper"/>
</mappers>
4. 使用 RowBounds 进行分页
在服务层或控制器中使用 RowBounds 进行分页查询。
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private SqlSession sqlSession;
public List<User> getUsersByPage(int currentPage, int pageSize) {
// 计算偏移量
int offset = (currentPage - 1) * pageSize;
// 创建 RowBounds 对象
RowBounds rowBounds = new RowBounds(offset, pageSize);
// 获取 UserMapper 实例
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询
List<User> userList = userMapper.selectAllUsers(rowBounds);
return userList;
}
}
注意:使用 RowBounds 进行分页时,Mapper 接口中的方法签名不需要显式地包含 RowBounds 参数。MyBatis 会在内部处理 RowBounds 参数。因此,Mapper 接口的方法签名保持不变,但在调用时需要传递 RowBounds 对象。
5. 控制器类
在控制器中调用服务层的方法,返回分页结果。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public List<User> getUsers(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
return userService.getUsersByPage(page, size);
}
}
1.2 使用 MyBatis 的插件(如 PageHelper)
PageHelper 是一个第三方分页插件,可以方便地实现物理分页。
使用步骤:
1. 添加依赖
在 pom.xml 中添加 PageHelper 依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
2. 配置插件
在 MyBatis 的配置文件中配置 PageHelper 插件:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 配置参数 -->
<property name="helperDialect" value="mysql"/>
<property name="reasonable" value="true"/>
</plugin>
</plugins>
3. 使用插件
在需要分页的地方使用 PageHelper.startPage 方法:
// 设置分页参数
int pageNum = 1; // 当前页码
int pageSize = 10; // 每页大小
// 开始分页
PageHelper.startPage(pageNum, pageSize);
// 执行查询
List<YourEntity> resultList = sqlSession.selectList("yourNamespace.yourSelectId");
// 获取分页信息
PageInfo<YourEntity> pageInfo = new PageInfo<>(resultList);
友情提示:由于 RowBounds 是在内存中进行分页,当数据量较大时,可能会导致性能问题。建议在数据量较大的情况下使用物理分页(如 PageHelper 或手动编写分页 SQL)。
2. 使用 MyBatis-Plus 进行分页
MyBatis-Plus 是一个 MyBatis 的增强工具,旨在简化开发、提高效率。它提供了内置的分页插件 PaginationInterceptor。
使用步骤:
2.1 添加依赖
在 pom.xml 中添加 MyBatis-Plus 依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
2.2 配置分页插件
在 Spring Boot 配置类中配置 PaginationInterceptor:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
2.3 使用分页插件
在需要分页的地方使用 Page 对象:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class YourService {
@Autowired
private YourMapper yourMapper;
public Page<YourEntity> getPaginatedData(int currentPage, int pageSize) {
// 创建分页对象
Page<YourEntity> page = new Page<>(currentPage, pageSize);
// 创建查询条件
QueryWrapper<YourEntity> queryWrapper = new QueryWrapper<>();
// 执行分页查询
Page<YourEntity> pageResult = yourMapper.selectPage(page, queryWrapper);
return pageResult;
}
}
特点:
- 内置分页插件:无需额外引入第三方插件,使用简单。
- 功能强大:支持多种分页方式,包括排序、过滤等。
- 集成良好:与 MyBatis-Plus 其他功能无缝集成。
3. 不使用 MyBatis 和 MyBatis-Plus 的插件进行分页
如果不使用 MyBatis 和 MyBatis-Plus 的插件,可以通过手动编写分页逻辑来实现分页功能。
3.1 手动编写分页 SQL
手动在 SQL 语句中添加分页逻辑,适用于需要高度定制化分页逻辑的情况。
示例代码:
<select id="selectPagedData" resultType="YourEntity">
SELECT *
FROM your_table
ORDER BY some_column
LIMIT #{offset}, #{pageSize}
</select>
Java 代码:
// 定义每页大小和当前页码
int pageSize = 10;
int currentPage = 1;
// 计算偏移量
int offset = (currentPage - 1) * pageSize;
// 创建参数对象
Map<String, Object> params = new HashMap<>();
params.put("offset", offset);
params.put("pageSize", pageSize);
// 执行查询
List<YourEntity> resultList = sqlSession.selectList("yourNamespace.selectPagedData", params);
特点:
- 灵活性高:可以根据具体需求编写复杂的分页逻辑。
- 性能较好:在数据库层面进行分页,性能较好。
- 复杂度较高:需要手动编写分页相关的 SQL 语句。
3.2 使用原生 JDBC 进行分页
使用原生 JDBC 进行分页操作,适用于不使用任何 ORM 框架的情况。
示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class JdbcPagingExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "your_user";
String password = "your_password";
int pageSize = 10;
int currentPage = 1;
int offset = (currentPage - 1) * pageSize;
try (Connection conn = DriverManager.getConnection(url, user, password)) {
String sql = "SELECT * FROM your_table ORDER BY some_column LIMIT ? OFFSET ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, pageSize);
pstmt.setInt(2, offset);
try (ResultSet rs = pstmt.executeQuery()) {
List<YourEntity> resultList = new ArrayList<>();
while (rs.next()) {
YourEntity entity = new YourEntity();
// 设置实体属性
resultList.add(entity);
}
// 处理结果集
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
特点:
- 完全控制:对 SQL 和数据库操作有完全的控制权。
- 灵活性高:可以根据具体需求编写复杂的分页逻辑。
- 复杂度较高:需要手动处理数据库连接、SQL 执行和结果集解析。