Java 分页指南:MyBatis 和 MyBatis-Plus 分页功能详解

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 执行和结果集解析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值