一、核心代码实现
1. pom.xml(依赖配置)
XML
<?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 http://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.7.18</version> <!-- 稳定版,适配PageHelper -->
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>oracle-page-demo</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- Spring Boot核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
<!-- Oracle驱动 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>21.9.0.0</version>
</dependency>
<!-- SQL解析 -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.6</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2. application.properties(配置文件)
bash
# 服务器端口
server.port=8080
# Oracle数据库配置
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORCL # 替换为你的Oracle地址
spring.datasource.username=your_username # 替换为你的用户名
spring.datasource.password=your_password # 替换为你的密码
# MyBatis配置
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.example.oraclepage.entity
mybatis.configuration.map-underscore-to-camel-case=true # 下划线转驼峰
# PageHelper配置
pagehelper.helper-dialect=oracle12c # 指定自定义的Oracle 12c方言
pagehelper.reasonable=true # 分页合理化(页码越界自动修正)
pagehelper.support-methods-arguments=true # 支持Mapper参数传分页参数
pagehelper.params=count=countSql
3. Oracle12cDialect.java(自定义方言)
java
package com.example.oraclepage.config;
import com.github.pagehelper.Page;
import com.github.pagehelper.dialect.AbstractHelperDialect;
import com.github.pagehelper.page.PageAutoDialect;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 自定义Oracle 12c分页方言(适配OFFSET ... FETCH语法)
*/
@Component
public class Oracle12cDialect extends AbstractHelperDialect {
// 注册方言别名,与配置文件中的pagehelper.helper-dialect对应
static {
PageAutoDialect.registerDialectAlias("oracle12c", Oracle12cDialect.class);
}
/**
* 生成Oracle 12c分页SQL(核心方法)
* @param sql 原始查询SQL
* @param page 分页对象
* @param pageKey 缓存Key
* @return 拼接后的分页SQL
*/
@Override
public String getPageSql(String sql, Page page, CacheKey pageKey) {
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 60);
sqlBuilder.append(sql);
// Oracle 12c分页语法:OFFSET 跳过行数 ROWS FETCH NEXT 取行数 ROWS ONLY
int offset = page.getStartRow(); // 跳过的行数((页码-1)*每页条数)
int limit = page.getPageSize(); // 每页条数
sqlBuilder.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(limit).append(" ROWS ONLY");
// 更新缓存Key(用于MyBatis缓存)
pageKey.update(offset);
pageKey.update(limit);
return sqlBuilder.toString();
}
/**
* 处理分页参数(Oracle 12c直接拼接SQL,无需额外参数处理)
*/
@Override
public Object processPageParameter(MappedStatement ms, Map<String, Object> paramMap, Page page, BoundSql boundSql) {
return paramMap;
}
}
4. User.java(实体类)
java
package com.example.oraclepage.entity;
/**
* 测试用用户实体类(需与数据库表字段对应)
*/
public class User {
private Long id; // 用户ID
private String userName; // 用户名(对应数据库user_name)
private String email; // 邮箱
// Getter & Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// toString
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", email='" + email + '\'' +
'}';
}
}
5. UserMapper.java(Mapper 接口)
java
package com.example.oraclepage.mapper;
import com.example.oraclepage.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 用户Mapper接口
*/
@Mapper
public interface UserMapper {
/**
* 查询所有用户(PageHelper自动分页)
*/
List<User> selectAllUsers();
}
6. UserMapper.xml(Mapper 映射文件)
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">
<mapper namespace="com.example.oraclepage.mapper.UserMapper">
<!-- 查询所有用户 -->
<select id="selectAllUsers" resultType="com.example.oraclepage.entity.User">
SELECT id, user_name, email FROM t_user <!-- 替换为你的实际表名 -->
</select>
</mapper>
7. UserService.java(业务层)
java
package com.example.oraclepage.service;
import com.example.oraclepage.entity.User;
import com.example.oraclepage.mapper.UserMapper;
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 UserService {
@Autowired
private UserMapper userMapper;
/**
* 分页查询用户
* @param pageNum 页码(从1开始)
* @param pageSize 每页条数
* @return 分页结果(包含数据+分页信息)
*/
public PageInfo<User> getUsersByPage(int pageNum, int pageSize) {
// 开启分页(核心:PageHelper自动拼接Oracle 12c分页SQL)
PageHelper.startPage(pageNum, pageSize);
// 执行查询(无需修改SQL,PageHelper自动处理)
List<User> userList = userMapper.selectAllUsers();
// 包装为PageInfo(包含总条数、总页数、当前页等信息)
return new PageInfo<>(userList);
}
}
8. OraclePageApplication.java(启动类)
java
package com.example.oraclepage;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 项目启动类
*/
@SpringBootApplication
@MapperScan("com.example.oraclepage.mapper") // 扫描Mapper接口
public class OraclePageApplication {
public static void main(String[] args) {
SpringApplication.run(OraclePageApplication.class, args);
}
}
9. 测试 Controller(可选)
java
package com.example.oraclepage.controller;
import com.example.oraclepage.entity.User;
import com.example.oraclepage.service.UserService;
import com.github.pagehelper.PageInfo;
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;
/**
* 测试接口
*/
@RestController
public class UserController {
@Autowired
private UserService userService;
/**
* 分页查询用户接口
* 访问示例:http://localhost:8080/users?pageNum=1&pageSize=10
*/
@GetMapping("/users")
public PageInfo<User> getUsers(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
return userService.getUsersByPage(pageNum, pageSize);
}
}
二、测试
sql
CREATE TABLE t_user (
id NUMBER PRIMARY KEY,
user_name VARCHAR2(50),
email VARCHAR2(100)
);
-- 插入测试数据
INSERT INTO t_user VALUES (1, 'zhangsan', 'zhangsan@test.com');
INSERT INTO t_user VALUES (2, 'lisi', 'lisi@test.com');
INSERT INTO t_user VALUES (3, 'wangwu', 'wangwu@test.com');
COMMIT;
-
启动项目 :运行
OraclePageApplication,访问http://localhost:8080/users?pageNum=1&pageSize=2; -
查看结果 :返回的 JSON 包含
list(当前页数据)、total(总条数)、pages(总页数)等信息,且底层执行的 SQL 为:sqlSELECT id, user_name, email FROM t_user OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY
三、注意事项
- 确保 Oracle 版本为 12c 及以上(
OFFSET ... FETCH是 12c 新增语法); - 替换配置文件中的数据库地址、用户名、密码为你的实际信息;
- 表名 / 字段名需与实体类、Mapper.xml 中的配置一致;
- PageHelper 版本建议与 Spring Boot 版本适配(避免依赖冲突)。