Oracle+Druid监控核心是驱动、Filter与解析器三者匹配:必须用ojdbc8.jar(如21.10.0.0)、druid-starter≥1.2.23、禁用WallFilter、手动注册WebStatFilter和StatViewServlet,并配置sql-parser: oracle。

Spring Boot 2.x 整合 Oracle + Druid 并开启 SQL 监控,核心难点不在“连得上”,而在“看得清”——Oracle 的 JDBC 驱动版本、Druid 的 SQL 解析能力、监控路径的 Filter 注册方式,三者稍有不匹配,/druid 页面就可能空白、SQL 不统计、慢查询漏报。
Oracle JDBC 驱动必须用 ojdbc8.jar,且不能混用旧版
Spring Boot 2.x 默认基于 JDK 8+,而 Oracle 官方明确要求:JDK 8 必须配 ojdbc8.jar(对应 Oracle 12cR2+),用 ojdbc6.jar 或 ojdbc7.jar 会导致 Druid 的 StatFilter 无法正确解析执行计划、ResultSet 元数据读取异常,最终表现为 SQL 列表为空或执行时间恒为 0。
- 确认 Maven 依赖中只存在一个 Oracle 驱动,且版本为
12.2.0.1或更高(如21.10.0.0):<dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>21.10.0.0</version> </dependency>
- 删掉项目里所有
ojdbc6.jar、ojdbc7.jar、classes12.jar等历史残留; - 如果用的是 Oracle 19c/21c,注意驱动类名仍是
oracle.jdbc.OracleDriver,不是oracle.jdbc.driver.OracleDriver(后者已废弃)。
druid-spring-boot-starter 的 version 必须 ≥ 1.1.10
早期 druid-spring-boot-starter 1.1.9 对 Oracle 支持不完整:它默认启用 WallFilter,但该 Filter 在 Oracle 场景下会误判部分合法语法(如 SELECT * FROM DUAL、ROWNUM 子句)为风险 SQL,直接拦截或不记录;同时其 StatFilter 对 Oracle 的绑定变量识别率低,导致同一条 SQL 被拆成多条“不同 SQL”统计。
- 强制升级 starter 版本:
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.23</version> </dependency>
- 在
application.yml中显式关闭WallFilter(除非你真需要 SQL 防注入,否则它对 Oracle 反而添乱):spring: datasource: druid: filter: wall: enabled: false - 确保
StatFilter是唯一启用的统计 Filter:filter: stat: enabled: true db-type: oracle
/druid 页面 404 或无数据?检查 WebStatFilter 是否注册成功
Druid 的监控页面不是自动暴露的——它依赖 WebStatFilter 拦截 HTTP 请求并采集 URI、Session、SQL 关联关系。Spring Boot 2.x 的自动配置在某些场景下(比如用了 Spring Security、自定义了 ServletWebServerFactory)会跳过该 Filter 注册,导致监控页打不开,或打开后全是 0。
- 手动注册
WebStatFilter和StatViewServlet(推荐,可控性强):@Configuration public class DruidConfig { @Bean public FilterRegistrationBean<WebStatFilter> webStatFilter() { FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>(); bean.setFilter(new WebStatFilter()); bean.addUrlPatterns("/*"); bean.addInitParameter("exclusions", "/druid/*,*.js,*.css,/images/*,/fonts/*"); return bean; } <p>@Bean public ServletRegistrationBean<StatViewServlet> statViewServlet() { ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); bean.addInitParameter("loginUsername", "admin"); bean.addInitParameter("loginPassword", "admin"); bean.addInitParameter("allow", "127.0.0.1,192.168.1.100"); // 生产务必限制 IP return bean; } } - 确认你的 Oracle 查询确实走的是 Druid 数据源:加一行日志验证
dataSource.getClass().getName()输出是否为com.alibaba.druid.pool.DruidDataSource; - 访问
/druid/sql.html后,点“刷新”再等 5–10 秒——Druid 默认每 60 秒聚合一次 SQL 统计,首次加载可能为空。
Oracle 特有 SQL 无法被识别?调整 sql-parser 配置
Druid 内置的 SQL 解析器对 Oracle 的 CONNECT BY、MERGE INTO、带 hint 的语句(如 /*+ INDEX(t idx_name) */)支持有限。若发现某类 SQL 总是显示为“OTHER”或归类错误,需主动指定 parser:
- 在
application.yml中加入:spring: datasource: druid: connection-properties: druid.stat.mergeSql=true;druid.stat.useWall=false # 强制使用 Oracle 解析器(Druid 1.2.16+ 支持) sql-parser: oracle - 如果仍无效,可临时关闭 SQL 合并(避免因解析失败丢数据):
filter: stat: merge-sql: false - 慢 SQL 阈值建议设为 1000ms 起步:
slow-sql-millis: 1000
Oracle 多数 OLTP 查询应在毫秒级,超过 1 秒基本可定位为慢。
真正卡住人的往往不是配置本身,而是 Oracle 驱动和 Druid 版本之间那层隐性兼容边界——它不报错,只沉默地不统计、不归类、不告警。上线前务必用一条带 ROWNUM 和绑定变量的简单查询,手动触发几次,再盯紧 /druid/sql.html 是否实时出现记录。


















