JDBC
JDBC(Java Database Connectivity)是JMeter中实现数据库交互的核心能力,通过一系列JDBC组件,可完成数据库的查询、插入、更新、删除等操作,适配接口测试数据准备、测试结果存储、数据对账校验、性能测试数据生成等场景。
一、核心JDBC组件及作用
JMeter提供多个JDBC相关组件,需按场景组合使用,核心组件及分工如下,与前文BeanShell、CSV、HTTP信息头管理器等组件形成协同体系:
| 组件名称 | 组件类型 | 核心作用 | 关联组件 |
|---|---|---|---|
| JDBC Connection Configuration(JDBC连接配置) | 配置元件 | 建立与数据库的连接,配置驱动、URL、账号密码、连接池等参数,是所有JDBC操作的基础 | 所有JDBC取样器、BeanShell后置处理程序(数据库交互) |
| JDBC Request(JDBC请求) | 取样器 | 执行SQL语句(查询/增删改),获取执行结果,支持参数化、结果变量存储 | JDBC连接配置、CSV数据文件设置、断言 |
| JDBC PreProcessor(JDBC前置处理器) | 前置处理器 | 在取样器执行前执行SQL(如测试前准备测试数据、清空表数据) | JDBC连接配置、接口取样器 |
| JDBC PostProcessor(JDBC后置处理器) | 后置处理器 | 在取样器执行后执行SQL(如测试后清理数据、更新测试状态) | JDBC连接配置、接口取样器、BeanShell后置处理程序 |
提示:实际测试中最常用的组合是“JDBC连接配置+JDBC请求”(直接执行SQL)、“JDBC连接配置+BeanShell后置处理程序”(自定义逻辑处理数据库交互),可根据是否需要自定义脚本逻辑选择对应方案。
二、前置准备:数据库驱动JAR包导入
JMeter本身不自带数据库驱动,需手动导入对应数据库的JDBC驱动JAR包,才能建立数据库连接,具体操作如下:
(一)常用数据库驱动及版本适配
- MySQL:驱动类为
com.mysql.cj.jdbc.Driver(MySQL 8.0+)、com.mysql.jdbc.Driver(MySQL 5.x),推荐JAR包:mysql-connector-java-8.0.33.jar(适配MySQL 8.0+,兼容5.x)。 - Oracle:驱动类为
oracle.jdbc.driver.OracleDriver,推荐JAR包:ojdbc8.jar(适配Oracle 12c/19c,JDK 8+)。 - SQL Server:驱动类为
com.microsoft.sqlserver.jdbc.SQLServerDriver,推荐JAR包:mssql-jdbc-12.4.1.jre8.jar(适配SQL Server 2016+,JDK 8+)。 - PostgreSQL:驱动类为
org.postgresql.Driver,推荐JAR包:postgresql-42.6.0.jar(适配PostgreSQL 10+)。
(二)JAR包导入步骤(全局生效,推荐)
- 下载对应数据库的JDBC驱动JAR包(注意版本与数据库、JDK适配,如JDK 8不支持适配JDK 11的驱动包);
- 将JAR包复制到JMeter安装目录的
lib/ext文件夹下(与前文BeanShell导入加密、POI JAR包路径一致); - 重启JMeter,确保驱动JAR包被加载(若不重启,会报“类找不到”错误,与前文JAR包导入问题一致)。
注意:避免导入同名不同版本的驱动JAR包,会导致类冲突;若需同时连接多种数据库,可将对应驱动JAR包同时放入lib/ext文件夹,无需额外配置。
三、核心配置:JDBC Connection Configuration详解
JDBC Connection Configuration是数据库连接的核心配置元件,需正确配置连接参数才能建立有效连接,以下按配置项逐一拆解,结合不同数据库给出示例,确保配置精准。
(一)添加路径与层级规范
右键目标组件(测试计划/线程组) → 添加 → 配置元件 → JDBC Connection Configuration
层级配置原则(与前文组件层级逻辑一致):
- 线程组层级(推荐):挂载在线程组下方,作用于该线程组内所有JDBC组件,适配单线程组操作同一数据库的场景,兼顾复用与隔离。
- 测试计划层级:挂载在测试计划下方,作用于所有线程组的JDBC组件,适用于多线程组操作同一数据库的场景,全局复用连接配置。
- 禁止挂载:避免挂载在取样器下方,会导致连接配置仅对单个取样器生效,且可能出现连接复用异常。
(二)核心配置项解析(全数据库适配)
-
Variable Name Bound to Pool(连接池变量名): 给当前连接池定义一个唯一变量名(如
mysql_test、oracle_prod),后续JDBC请求、BeanShell脚本需通过该变量名关联此连接配置。若多个连接配置,变量名需唯一,避免混淆。 -
Database URL(数据库连接URL): 指定数据库连接地址,格式随数据库类型变化,核心参数包括主机地址、端口、数据库名、编码格式、时区等,示例如下:
// MySQL 8.0+ jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 // MySQL 5.x jdbc:mysql://192.168.1.100:3306/test_db?useSSL=false&characterEncoding=UTF-8 // Oracle jdbc:oracle:thin:@192.168.1.101:1521:ORCL // SQL Server jdbc:sqlserver://localhost:1433;DatabaseName=test_db;encrypt=false // PostgreSQL jdbc:postgresql://localhost:5432/test_db?characterEncoding=UTF-8 关键参数说明:`useSSL=false`(关闭SSL验证,避免开发环境连接报错)、`serverTimezone=UTC`(MySQL 8.0+必填,适配时区)、`characterEncoding=UTF-8`(避免中文乱码)。 -
JDBC Driver Class(JDBC驱动类): 选择对应数据库的驱动类,需与导入的JAR包匹配,不可手动输入(手动输入易出错),下拉选择示例:
- MySQL 8.0+:com.mysql.cj.jdbc.Driver
- MySQL 5.x:com.mysql.jdbc.Driver
- Oracle:oracle.jdbc.driver.OracleDriver
- SQL Server:com.microsoft.sqlserver.jdbc.SQLServerDriver
- PostgreSQL:org.postgresql.Driver
-
Username/Password(数据库账号密码): 填写数据库的登录账号与密码,支持引用JMeter变量(如
${db_username}、${db_password}),可通过CSV数据文件设置存储多环境账号密码,适配多环境测试(与前文CSV变量联动逻辑一致)。 -
Connection Pool Configuration(连接池配置,性能测试必备): 控制数据库连接池的参数,适配高并发性能测试,避免因连接数不足导致测试失败,核心参数:
- Max Number of Connections(最大连接数):默认0(无限制),性能测试建议设为线程数的1.5-2倍(如100线程设为150),避免连接耗尽。
- Max Wait (ms)(最大等待时间):默认10000ms,连接池无可用连接时的等待时间,超时则报错,可根据数据库性能调整。
- Validation Query(验证查询语句):用于校验连接有效性,如MySQL填
SELECT 1,Oracle填SELECT 1 FROM DUAL,避免使用无效连接执行SQL。
四、JDBC Request取样器实战
JDBC Request是直接执行SQL语句的核心取样器,支持查询、增删改等所有SQL操作,同时可将执行结果存入变量,供后续接口、断言、BeanShell脚本引用,以下结合场景讲解配置与用法。
(一)添加路径与关联配置
右键线程组 → 添加 → 取样器 → JDBC Request
核心关联:在JDBC Request的“Variable Name of Pool declared in JDBC Connection Configuration”下拉框,选择JDBC连接配置定义的连接池变量名(如mysql_test),确保取样器关联正确的数据库连接。
(二)核心配置项解析
-
Query Type(查询类型): 根据SQL语句类型选择,不同类型对应不同的执行逻辑与结果处理方式:
- Select Statement(查询语句):执行
SELECT语句,返回查询结果集,支持将结果存入变量。 - Update Statement(更新语句):执行
INSERT、UPDATE、DELETE语句,返回受影响的行数,无结果集。 - Callable Statement(存储过程):执行数据库存储过程,适用于复杂业务逻辑的SQL操作。
- Prepared Select Statement(预编译查询)/Prepared Update Statement(预编译更新):支持参数化SQL,通过
?占位符接收参数,安全性更高,适配动态SQL场景。
- Select Statement(查询语句):执行
-
SQL Query(SQL语句): 填写需执行的SQL语句,支持固定SQL、参数化SQL(引用JMeter变量),示例如下:
-- 固定查询SQL ``SELECT order_no, amount FROM order_info WHERE status = 'SUCCESS'; `` -- 参数化SQL(引用CSV变量) ``SELECT * FROM user_info WHERE username = '${username}'; `` -- 预编译SQL(占位符) ``UPDATE order_info SET status = ? WHERE order_no = ?;` 注意:SQL语句末尾无需加
;(分号),否则可能导致执行报错;若需执行多条SQL,需勾选“Allow MultiQueries”(部分数据库支持)。 -
Parameter values/Types(参数值/类型,预编译SQL专用): 对应预编译SQL中的
?占位符,参数值按顺序填写,多个参数用逗号分隔(如FAIL, ${orderNo});参数类型选择对应的数据类型(如VARCHAR、INT、DATE),需与数据库字段类型一致。 -
Result variable name(结果变量名): 将查询结果集存入指定变量(如
orderResult),后续可通过${orderResult_0_0}(第1行第1列)、${orderResult_1_2}(第2行第3列)引用结果集中的数据,适配数据对账场景。 -
Return variable name(返回变量名): 存储查询结果的总行数(如
totalRows),后续可通过${totalRows}引用,适用于验证查询结果数量(如断言总行数大于0)。
五、高频实战场景案例
结合真实测试需求,梳理4类高频场景,涵盖数据准备、结果存储、数据对账、多环境适配,重点衔接前文CSV、BeanShell、断言等组件,确保场景连贯可落地。
(一)场景一:测试前数据准备(JDBC前置处理器+CSV)
目标:接口测试前,通过JDBC前置处理器从数据库查询测试数据(如可用账号),存入变量供接口请求使用,结合CSV数据文件设置实现多组数据批量测试。
配置步骤:
- 前置准备:导入MySQL驱动JAR包,配置JDBC连接配置(连接池变量名
mysql_test,连接测试库test_db)。 - 添加JDBC前置处理器(挂载在接口取样器下方):
- 关联连接池变量名:
mysql_test; - 查询类型:Select Statement;
- SQL语句:
SELECT username, password FROM user_info WHERE status = 'ENABLE' LIMIT 1; - 结果变量名:
userData。
- 关联连接池变量名:
- 接口取样器配置:请求体引用变量
${userData_0_0}(用户名)、${userData_0_1}(密码),实现动态获取测试账号。 - 批量扩展:结合CSV数据文件设置,通过
LIMIT ${csvIndex}, 1(${csvIndex}为CSV变量),实现多组账号循环获取。
预期效果:每次接口请求前,自动从数据库获取可用账号,无需手动维护测试数据,适配账号动态变化的场景。
(二)场景二:测试结果存储(BeanShell后置处理程序+JDBC)
目标:接口测试完成后,将响应结果(订单号、状态、测试时间)通过BeanShell后置处理程序写入数据库,实现测试结果持久化,衔接前文BeanShell数据库交互逻辑。
配置步骤:
- 前置准备:导入MySQL驱动JAR包,配置JDBC连接配置(连接池变量名
mysql_test)。 - 添加BeanShell后置处理程序(挂载在接口取样器下方),编写脚本(复用前文逻辑,优化变量关联):
// 1. 导入JDBC相关类(来自驱动JAR包)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import org.json.JSONObject;
// 2. 解析接口响应结果(接口返回JSON格式订单信息)
String responseBody = Response.getResponseDataAsString();
JSONObject json = new JSONObject(responseBody);
String orderNo = json.getString("orderNo");
String status = json.getString("status");
String amount = json.getString("amount");
// 生成测试时间(格式化)
String testTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
// 3. 从JDBC连接配置提取连接信息(避免硬编码,适配多环境)
String url = vars.get("db_url"); // 从用户定义变量获取
String username = vars.get("db_username");
String password = vars.get("db_password");
// 4. 连接数据库并写入测试结果
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url, username, password);
String sql = "INSERT INTO test_result (order_no, amount, status, test_time) VALUES (?, ?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, orderNo);
pstmt.setString(2, amount);
pstmt.setString(3, status);
pstmt.setString(4, testTime);
int rows = pstmt.executeUpdate();
log.info("测试结果写入成功,影响行数:" + rows);
} catch (Exception e) {
log.error("测试结果写入失败:" + e.getMessage());
e.printStackTrace();
} finally {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
}
- 辅助配置:添加用户定义的变量,存储
db_url、db_username、db_password,快速切换测试/生产环境数据库。 - 辅助配置:添加用户定义的变量,存储
db_url、db_username、db_password,快速切换测试/生产环境数据库。
(三)场景三:数据对账校验(JDBC请求+断言)
目标:接口调用完成后,通过JDBC请求查询数据库中的订单数据,与接口响应结果对比,通过断言验证数据一致性(如接口返回的金额与数据库一致)。
配置步骤:
- 添加接口取样器:调用下单接口,通过JSON提取器提取响应中的
orderNo(订单号)、amount(金额),存入变量。 - 添加JDBC请求(挂载在接口取样器下方):
- 关联连接池变量名:
mysql_test; - 查询类型:Select Statement;
- SQL语句:
SELECT amount FROM order_info WHERE order_no = '${orderNo}'(${orderNo}为接口响应提取的变量); - 结果变量名:
dbAmount; - 返回变量名:
dbRows。
- 关联连接池变量名:
- 添加响应断言:
- 断言字段:响应数据(或JMeter变量);
- 断言条件:
${dbAmount_0_0}equals${amount}(数据库金额与接口响应金额一致); - 补充断言:
${dbRows}greater than 0(确保数据库存在该订单)。
预期效果:若数据库金额与接口响应金额不一致,或数据库无该订单,断言失败,标记测试用例异常。
(四)场景四:性能测试数据生成(JDBC请求+循环)
目标:性能测试前,通过JDBC请求批量生成测试数据(如1000条用户数据),存入数据库,为高并发接口测试提供数据支撑。
配置步骤:
- 配置JDBC连接配置,确保数据库支持高并发写入(调整连接池最大连接数为200)。
- 添加循环控制器(线程组内):循环次数设为1000(生成1000条数据)。
- 添加JDBC请求(循环控制器内):
- 查询类型:Prepared Update Statement;
- 预编译SQL:
INSERT INTO user_info (username, password, create_time) VALUES (?, ?, ?); - 参数值:
user_${__threadNum}_${__time(yyyyMMddHHmmss,)}, 123456, ${__time(yyyy-MM-dd HH:mm:ss,)}(通过函数生成唯一用户名、当前时间); - 参数类型:VARCHAR, VARCHAR, TIMESTAMP。
- 线程组配置:线程数设为10,循环次数设为100,总生成数据量10*100=1000条。
预期效果:执行完成后,数据库生成1000条唯一用户数据,满足性能测试的数据需求。
六、常见问题与排查方案
JMeter JDBC操作的错误主要集中在驱动配置、连接参数、SQL语法、变量关联等方面,以下梳理6类高频问题,结合成因与排查步骤,帮助快速定位解决,部分问题与前文BeanShell JAR包导入问题复用排查逻辑。
(一)报错“ClassNotFoundException: com.mysql.cj.jdbc.Driver”
常见成因:未导入驱动JAR包、JAR包路径错误、未重启JMeter、JAR包版本与数据库不兼容。
排查步骤:
1. 确认驱动JAR包已放入`lib/ext`文件夹,路径无错误;
重启JMeter,确保JAR包被加载;
3. 核对驱动类与JAR包匹配(如MySQL 8.0+用`com.mysql.cj.jdbc.Driver`,而非5.x的驱动类);
更换适配的JAR包版本,避免版本不兼容。
(二)报错“Communications link failure”(连接失败)
常见成因:数据库URL错误、数据库服务未启动、主机地址/端口错误、防火墙拦截。
排查步骤:
1. 核对数据库URL的主机地址、端口、数据库名是否正确;
确认数据库服务已启动,且能通过本地客户端连接(如MySQL用Navicat测试连接);
3. 关闭防火墙(开发/测试环境),或开放对应端口(如MySQL 3306端口);
MySQL 8.0+需添加`serverTimezone=UTC`参数,避免时区导致的连接失败。
(三)SQL执行报错“Unknown column 'xxx' in 'field list'”
常见成因:字段名拼写错误、字段名包含特殊字符、SQL语句语法错误(如多余空格、缺少引号)。
排查步骤: 1. 核对字段名与数据库表结构一致,区分大小写(部分数据库敏感,如Oracle); 2. 若字段名包含特殊字符(如下划线、中文),用反引号`包裹(MySQL)或双引号包裹(Oracle); 3. 将SQL语句复制到数据库客户端执行,验证语法正确性,再复制到JMeter中(去除末尾;)。
(四)参数化SQL无结果/结果错误
常见成因:变量未正确赋值、变量值与数据库字段类型不匹配、参数顺序错误(预编译SQL)。
排查步骤: 1. 通过log.info("变量值:" + ${username})打印变量,确认变量已正确赋值; 2. 核对变量值类型与数据库字段类型一致(如数字类型无需加引号,字符串类型需加引号); 3. 预编译SQL的参数顺序需与?占位符顺序一致,参数值数量与占位符数量匹配。
(五)高并发场景下连接耗尽报错“Timeout waiting for connection”
常见成因:连接池最大连接数不足、连接未及时释放、SQL执行耗时过长。
排查步骤:
1. 调整JDBC连接配置的“Max Number of Connections”,设为线程数的1.5-2倍;
优化SQL语句,减少执行耗时(如添加索引、简化查询逻辑);
3. 确保SQL执行完成后连接正常释放(JMeter默认自动释放,避免自定义脚本中未关闭连接);
增加“Max Wait (ms)”值,延长连接等待时间。
(六)中文乱码问题(数据库写入/查询中文显示乱码)
常见成因:数据库URL未指定编码、数据库表字符集不是UTF-8、JMeter默认编码不是UTF-8。
排查步骤:
1. 数据库URL添加`characterEncoding=UTF-8`参数;
确认数据库表字符集为UTF-8(如MySQL表字符集设为utf8mb4);
3. 打开jmeter.properties文件,设置`sampleresult.default.encoding=UTF-8`,重启JMeter;
参数化中文变量时,确保CSV文件编码为UTF-8。

浙公网安备 33010602011771号