or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdexceptions.mdindex.mdinterceptors.mdjdbc-advanced.mdjdbc-core.mdjdbc-high-availability.mdlogging-monitoring.mdtype-system.mdutilities.mdxdevapi-core.mdxdevapi-crud.mdxdevapi-sql.md

interceptors.mddocs/

0

# Interceptors

1

2

Query and connection lifecycle interceptors for customizing driver behavior. Interceptors allow you to hook into query execution and connection events.

3

4

## Capabilities

5

6

### Query Interceptor

7

8

Interface for intercepting query execution.

9

10

```java { .api }

11

package com.mysql.cj.interceptors;

12

13

public interface QueryInterceptor {

14

// Initialize interceptor

15

QueryInterceptor init(MysqlConnection conn, Properties props, Log log);

16

17

// Pre-process query (before execution)

18

<T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);

19

20

// Check if should execute only at top level

21

boolean executeTopLevelOnly();

22

23

// Destroy interceptor

24

void destroy();

25

26

// Post-process query (after execution)

27

<T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

28

T originalResultSet, ServerSession serverSession);

29

}

30

```

31

32

Usage:

33

34

```java

35

// Implement custom query interceptor

36

public class MyQueryInterceptor implements QueryInterceptor {

37

private Log log;

38

39

public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {

40

this.log = log;

41

return this;

42

}

43

44

public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {

45

log.logInfo("Executing query: " + sql.get());

46

return null; // null means proceed with execution

47

}

48

49

public boolean executeTopLevelOnly() {

50

return false; // Also intercept nested queries

51

}

52

53

public void destroy() {

54

// Cleanup

55

}

56

57

public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

58

T originalResultSet, ServerSession serverSession) {

59

log.logInfo("Query completed: " + sql.get());

60

return originalResultSet;

61

}

62

}

63

64

// Configure interceptor in URL

65

String url = "jdbc:mysql://localhost:3306/mydb" +

66

"?queryInterceptors=com.mycompany.MyQueryInterceptor";

67

Connection conn = DriverManager.getConnection(url, "user", "pass");

68

69

// All queries will be intercepted

70

Statement stmt = conn.createStatement();

71

stmt.executeQuery("SELECT * FROM users");

72

```

73

74

### Connection Lifecycle Interceptor

75

76

Interface for intercepting connection lifecycle events.

77

78

```java { .api }

79

package com.mysql.cj.jdbc.interceptors;

80

81

public interface ConnectionLifecycleInterceptor {

82

// Initialize interceptor

83

ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log);

84

85

// Destroy interceptor

86

void destroy();

87

88

// Called when new session is created

89

void createNewSession();

90

91

// Called when transaction begins

92

void transactionBegun();

93

94

// Called when transaction completes (commit or rollback)

95

void transactionCompleted();

96

}

97

```

98

99

Usage:

100

101

```java

102

// Implement custom connection lifecycle interceptor

103

public class MyConnectionLifecycleInterceptor implements ConnectionLifecycleInterceptor {

104

private Log log;

105

106

public ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log) {

107

this.log = log;

108

return this;

109

}

110

111

public void destroy() {

112

// Cleanup

113

}

114

115

public void createNewSession() {

116

log.logInfo("New database session created");

117

}

118

119

public void transactionBegun() {

120

log.logInfo("Transaction started");

121

}

122

123

public void transactionCompleted() {

124

log.logInfo("Transaction completed");

125

}

126

}

127

128

// Configure interceptor in URL

129

String url = "jdbc:mysql://localhost:3306/mydb" +

130

"?connectionLifecycleInterceptors=com.mycompany.MyConnectionLifecycleInterceptor";

131

Connection conn = DriverManager.getConnection(url, "user", "pass");

132

133

// Lifecycle events will be intercepted

134

conn.setAutoCommit(false); // transactionBegun() called

135

stmt.executeUpdate("INSERT INTO users (name) VALUES ('Alice')");

136

conn.commit(); // transactionCompleted() called

137

```

138

139

### Result Set Scanner Interceptor

140

141

Built-in interceptor for scanning result sets.

142

143

```java { .api }

144

package com.mysql.cj.jdbc.interceptors;

145

146

public class ResultSetScannerInterceptor implements QueryInterceptor {

147

// Scans result sets for specific patterns

148

// Configure via properties:

149

// resultSetScannerRegex - regex pattern to match

150

151

public QueryInterceptor init(MysqlConnection conn, Properties props, Log log);

152

public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);

153

public boolean executeTopLevelOnly();

154

public void destroy();

155

public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

156

T originalResultSet, ServerSession serverSession);

157

}

158

```

159

160

Usage:

161

162

```java

163

// Scan result sets for sensitive data patterns

164

String url = "jdbc:mysql://localhost:3306/mydb" +

165

"?queryInterceptors=com.mysql.cj.jdbc.interceptors.ResultSetScannerInterceptor" +

166

"&resultSetScannerRegex=\\d{3}-\\d{2}-\\d{4}"; // SSN pattern

167

Connection conn = DriverManager.getConnection(url, "user", "pass");

168

169

// Will scan all result sets and log matches

170

```

171

172

### Server Status Diff Interceptor

173

174

Built-in interceptor for tracking server status changes.

175

176

```java { .api }

177

package com.mysql.cj.jdbc.interceptors;

178

179

public class ServerStatusDiffInterceptor implements QueryInterceptor {

180

// Tracks changes in server status variables before/after queries

181

182

public QueryInterceptor init(MysqlConnection conn, Properties props, Log log);

183

public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);

184

public boolean executeTopLevelOnly();

185

public void destroy();

186

public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

187

T originalResultSet, ServerSession serverSession);

188

}

189

```

190

191

Usage:

192

193

```java

194

// Track server status changes

195

String url = "jdbc:mysql://localhost:3306/mydb" +

196

"?queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";

197

Connection conn = DriverManager.getConnection(url, "user", "pass");

198

199

// Will log changes in server status variables

200

```

201

202

### Session Association Interceptor

203

204

Built-in interceptor for associating sessions with application context.

205

206

```java { .api }

207

package com.mysql.cj.jdbc.interceptors;

208

209

public class SessionAssociationInterceptor implements ConnectionLifecycleInterceptor {

210

// Associates session with application context

211

212

public ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log);

213

public void destroy();

214

public void createNewSession();

215

public void transactionBegun();

216

public void transactionCompleted();

217

}

218

```

219

220

### Multiple Interceptors

221

222

You can configure multiple interceptors by separating them with commas.

223

224

Usage:

225

226

```java

227

// Configure multiple query interceptors

228

String url = "jdbc:mysql://localhost:3306/mydb" +

229

"?queryInterceptors=" +

230

"com.mycompany.LoggingInterceptor," +

231

"com.mycompany.MetricsInterceptor," +

232

"com.mycompany.SecurityInterceptor";

233

234

// Configure multiple connection lifecycle interceptors

235

String url2 = "jdbc:mysql://localhost:3306/mydb" +

236

"?connectionLifecycleInterceptors=" +

237

"com.mycompany.PoolingInterceptor," +

238

"com.mycompany.AuditInterceptor";

239

240

Connection conn = DriverManager.getConnection(url, "user", "pass");

241

```

242

243

### Advanced Query Interceptor Example

244

245

Complete example showing advanced query interception:

246

247

```java

248

public class MetricsQueryInterceptor implements QueryInterceptor {

249

private Log log;

250

private Map<String, Long> queryTimes = new ConcurrentHashMap<>();

251

private Map<String, AtomicLong> queryCount = new ConcurrentHashMap<>();

252

253

public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {

254

this.log = log;

255

return this;

256

}

257

258

public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {

259

String query = sql.get();

260

queryTimes.put(query, System.currentTimeMillis());

261

queryCount.computeIfAbsent(query, k -> new AtomicLong()).incrementAndGet();

262

return null;

263

}

264

265

public boolean executeTopLevelOnly() {

266

return true;

267

}

268

269

public void destroy() {

270

// Log metrics summary

271

log.logInfo("Query Metrics Summary:");

272

for (Map.Entry<String, AtomicLong> entry : queryCount.entrySet()) {

273

log.logInfo(entry.getKey() + ": executed " + entry.getValue() + " times");

274

}

275

}

276

277

public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

278

T originalResultSet, ServerSession serverSession) {

279

String query = sql.get();

280

Long startTime = queryTimes.remove(query);

281

if (startTime != null) {

282

long duration = System.currentTimeMillis() - startTime;

283

if (duration > 1000) {

284

log.logWarn("Slow query (" + duration + "ms): " + query);

285

}

286

}

287

return originalResultSet;

288

}

289

}

290

```

291

292

### Parameter Bindings Access

293

294

Query interceptors can access parameter bindings:

295

296

```java

297

public class ParameterLoggingInterceptor implements QueryInterceptor {

298

private Log log;

299

300

public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {

301

this.log = log;

302

return this;

303

}

304

305

public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {

306

if (interceptedQuery instanceof PreparedQuery) {

307

PreparedQuery<?> pq = (PreparedQuery<?>) interceptedQuery;

308

ParameterBindings bindings = pq.getParameterBindings();

309

310

StringBuilder sb = new StringBuilder("Query: ");

311

sb.append(sql.get());

312

sb.append("\nParameters: ");

313

sb.append(bindings.toString(true));

314

315

log.logDebug(sb.toString());

316

}

317

return null;

318

}

319

320

public boolean executeTopLevelOnly() {

321

return false;

322

}

323

324

public void destroy() {}

325

326

public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,

327

T originalResultSet, ServerSession serverSession) {

328

return originalResultSet;

329

}

330

}

331

```

332