or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddatabase-templates.mddml-operations.mdindex.mdquery-construction.mdsql-expressions.mdtype-system.md

configuration.mddocs/

0

# Configuration and Customization

1

2

QueryDSL SQL provides a flexible configuration system for customizing SQL generation, type mappings, naming strategies, schema mappings, and execution monitoring through listeners and custom mappings.

3

4

## Capabilities

5

6

### Core Configuration

7

8

Central configuration class that coordinates all aspects of QueryDSL SQL behavior.

9

10

```java { .api }

11

/**

12

* Central configuration class for QueryDSL SQL operations

13

*/

14

public class Configuration {

15

/**

16

* Creates configuration with specified SQL templates

17

* @param templates Database-specific SQL templates

18

*/

19

public Configuration(SQLTemplates templates);

20

21

/**

22

* Gets the SQL templates for this configuration

23

* @return SQL templates instance

24

*/

25

public SQLTemplates getTemplates();

26

27

/**

28

* Registers a custom type for a specific table column

29

* @param table Table name

30

* @param column Column name

31

* @param type Type handler to use

32

*/

33

public void register(String table, String column, Type<?> type);

34

35

/**

36

* Registers a path mapping for schema and table resolution

37

* @param table Table identifier

38

* @param property Property name

39

* @param path Path to map to

40

*/

41

public void register(String table, String property, Path<?> path);

42

43

/**

44

* Registers a global type mapping by SQL type name

45

* @param typeName SQL type name

46

* @param type Type handler to use

47

*/

48

public void registerType(String typeName, Type<?> type);

49

50

/**

51

* Adds a SQL execution listener

52

* @param listener Listener to add

53

*/

54

public void addListener(SQLListener listener);

55

56

/**

57

* Removes a SQL execution listener

58

* @param listener Listener to remove

59

*/

60

public void removeListener(SQLListener listener);

61

}

62

```

63

64

**Usage Examples:**

65

66

```java

67

// Basic configuration setup

68

SQLTemplates templates = PostgreSQLTemplates.builder().build();

69

Configuration config = new Configuration(templates);

70

71

// Register custom type for specific column

72

config.register("user", "status", new EnumByNameType<>(UserStatus.class));

73

74

// Register global type mapping

75

config.registerType("uuid", new UtilUUIDType());

76

77

// Add execution listener

78

config.addListener(new SQLBaseListener() {

79

@Override

80

public void notifyQuery(SQLListenerContext context) {

81

logger.info("Executing query: {}", context.getSQL());

82

}

83

});

84

85

// Create query factory with configuration

86

SQLQueryFactory queryFactory = new SQLQueryFactory(config, dataSource);

87

```

88

89

### Type Registration

90

91

System for registering and managing custom type mappings at various scopes.

92

93

```java { .api }

94

/**

95

* JDBC to Java type mapping registry

96

*/

97

public class JDBCTypeMapping {

98

/**

99

* Registers a type for specific JDBC type codes

100

* @param type Type handler to register

101

* @param jdbcTypes JDBC type codes this handler supports

102

*/

103

public void register(Type<?> type, int... jdbcTypes);

104

105

/**

106

* Gets registered type for JDBC type code

107

* @param jdbcType JDBC type code

108

* @param typeName SQL type name

109

* @param size Column size

110

* @param digits Decimal digits

111

* @return Appropriate type handler

112

*/

113

public Type<?> getType(int jdbcType, String typeName, int size, int digits);

114

}

115

116

/**

117

* Java class to QueryDSL type mapping registry

118

*/

119

public class JavaTypeMapping {

120

/**

121

* Registers a type handler for a Java class

122

* @param javaType Java class

123

* @param type Type handler

124

*/

125

public void register(Class<?> javaType, Type<?> type);

126

127

/**

128

* Gets type handler for Java class

129

* @param javaType Java class to get handler for

130

* @return Type handler or null if not registered

131

*/

132

public Type<?> getType(Class<?> javaType);

133

}

134

```

135

136

**Usage Examples:**

137

138

```java

139

Configuration config = new Configuration(templates);

140

141

// Register type for specific JDBC types

142

JDBCTypeMapping jdbcMapping = config.getJDBCTypeMapping();

143

jdbcMapping.register(new UUIDType(), Types.OTHER, Types.VARCHAR);

144

145

// Register type for Java classes

146

JavaTypeMapping javaMapping = config.getJavaTypeMapping();

147

javaMapping.register(Money.class, new MoneyType());

148

javaMapping.register(PhoneNumber.class, new PhoneNumberType());

149

150

// Column-specific type registration takes precedence

151

config.register("user", "phone", new InternationalPhoneType());

152

```

153

154

### Name Mapping

155

156

Flexible naming strategies for mapping between Java identifiers and SQL identifiers.

157

158

```java { .api }

159

/**

160

* Interface for mapping between Java and SQL identifiers

161

*/

162

public interface NameMapping {

163

/**

164

* Maps Java identifier to SQL identifier

165

* @param javaIdentifier Java field/property name

166

* @return SQL column/table name

167

*/

168

String getColumnOverride(String javaIdentifier);

169

170

/**

171

* Maps SQL identifier to Java identifier

172

* @param sqlIdentifier SQL column/table name

173

* @return Java field/property name

174

*/

175

String getPropertyOverride(String sqlIdentifier);

176

}

177

178

/**

179

* Chains multiple name mappings together

180

*/

181

public class ChainedNameMapping implements NameMapping {

182

public ChainedNameMapping(NameMapping... mappings);

183

public ChainedNameMapping add(NameMapping mapping);

184

}

185

186

/**

187

* Changes letter case of identifiers

188

*/

189

public class ChangeLetterCaseNameMapping implements NameMapping {

190

public enum LetterCase { UPPER, LOWER }

191

192

public ChangeLetterCaseNameMapping(LetterCase letterCase);

193

public ChangeLetterCaseNameMapping(LetterCase columnCase, LetterCase propertyCase);

194

}

195

196

/**

197

* Pre-configured mappings for specific naming conventions

198

*/

199

public class PreConfiguredNameMapping implements NameMapping {

200

public static final NameMapping CAMEL_CASE_TO_LOWER_WITH_UNDERSCORES;

201

public static final NameMapping UPPER_WITH_UNDERSCORES_TO_CAMEL_CASE;

202

203

public PreConfiguredNameMapping(Map<String, String> columnToProperty);

204

}

205

```

206

207

**Usage Examples:**

208

209

```java

210

// Configure camelCase to snake_case mapping

211

NameMapping nameMapping = PreConfiguredNameMapping.CAMEL_CASE_TO_LOWER_WITH_UNDERSCORES;

212

config.setNameMapping(nameMapping);

213

214

// Chain multiple naming strategies

215

NameMapping chainedMapping = new ChainedNameMapping(

216

new ChangeLetterCaseNameMapping(LetterCase.LOWER),

217

PreConfiguredNameMapping.CAMEL_CASE_TO_LOWER_WITH_UNDERSCORES

218

);

219

220

// Custom name mapping

221

Map<String, String> customMappings = new HashMap<>();

222

customMappings.put("user_id", "userId");

223

customMappings.put("created_at", "createdTime");

224

customMappings.put("is_active", "active");

225

226

NameMapping customMapping = new PreConfiguredNameMapping(customMappings);

227

config.setNameMapping(customMapping);

228

```

229

230

### Schema Mapping

231

232

Configuration for handling database schemas and table name resolution.

233

234

```java { .api }

235

/**

236

* Represents schema and table combination

237

*/

238

public class SchemaAndTable {

239

/**

240

* Creates schema and table reference

241

* @param schema Schema name (can be null)

242

* @param table Table name

243

*/

244

public SchemaAndTable(String schema, String table);

245

246

/**

247

* Gets the schema name

248

* @return Schema name or null

249

*/

250

public String getSchema();

251

252

/**

253

* Gets the table name

254

* @return Table name

255

*/

256

public String getTable();

257

258

/**

259

* Creates qualified table name

260

* @return Schema.table or just table if no schema

261

*/

262

public String getQualifiedName();

263

}

264

```

265

266

**Usage Examples:**

267

268

```java

269

// Configure default schema

270

Configuration config = new Configuration(templates);

271

config.setSchema("app_schema");

272

273

// Register table with specific schema

274

config.register(new SchemaAndTable("audit", "user_changes"), qUserAudit);

275

276

// Multi-tenant schema mapping

277

Map<String, String> tenantSchemas = new HashMap<>();

278

tenantSchemas.put("tenant1", "tenant1_schema");

279

tenantSchemas.put("tenant2", "tenant2_schema");

280

281

// Dynamic schema resolution

282

String currentTenant = getCurrentTenant();

283

String schema = tenantSchemas.get(currentTenant);

284

config.setSchema(schema);

285

```

286

287

### SQL Execution Listeners

288

289

Comprehensive listener system for monitoring and customizing SQL execution behavior.

290

291

```java { .api }

292

/**

293

* Core interface for SQL execution listeners

294

*/

295

public interface SQLListener {

296

/**

297

* Called before query execution

298

* @param context Execution context with SQL and parameters

299

*/

300

void notifyQuery(SQLListenerContext context);

301

302

/**

303

* Called before delete execution

304

* @param context Execution context

305

*/

306

void notifyDelete(SQLListenerContext context);

307

308

/**

309

* Called before insert execution

310

* @param context Execution context

311

*/

312

void notifyInsert(SQLListenerContext context);

313

314

/**

315

* Called before update execution

316

* @param context Execution context

317

*/

318

void notifyUpdate(SQLListenerContext context);

319

320

/**

321

* Called before merge execution

322

* @param context Execution context

323

*/

324

void notifyMerge(SQLListenerContext context);

325

}

326

327

/**

328

* Extended listener interface with detailed execution information

329

*/

330

public interface SQLDetailedListener extends SQLListener {

331

/**

332

* Called after successful query execution

333

* @param context Execution context

334

* @param duration Execution duration in milliseconds

335

*/

336

void notifyQueryEnd(SQLListenerContext context, long duration);

337

338

/**

339

* Called when query execution fails

340

* @param context Execution context

341

* @param exception Exception that occurred

342

*/

343

void notifyException(SQLListenerContext context, Exception exception);

344

}

345

```

346

347

**Usage Examples:**

348

349

```java

350

// Logging listener

351

SQLListener loggingListener = new SQLBaseListener() {

352

@Override

353

public void notifyQuery(SQLListenerContext context) {

354

logger.debug("Query: {} with params: {}",

355

context.getSQL(), context.getBindings());

356

}

357

};

358

359

// Performance monitoring listener

360

SQLDetailedListener perfListener = new SQLListenerAdapter() {

361

@Override

362

public void notifyQueryEnd(SQLListenerContext context, long duration) {

363

if (duration > 1000) { // Log slow queries

364

logger.warn("Slow query ({}ms): {}", duration, context.getSQL());

365

}

366

}

367

368

@Override

369

public void notifyException(SQLListenerContext context, Exception exception) {

370

logger.error("Query failed: {} - {}", context.getSQL(), exception.getMessage());

371

}

372

};

373

374

// Add listeners to configuration

375

config.addListener(loggingListener);

376

config.addListener(perfListener);

377

```

378

379

### Listener Context and Utilities

380

381

Context objects and utilities for working with SQL execution listeners.

382

383

```java { .api }

384

/**

385

* Execution context provided to listeners

386

*/

387

public interface SQLListenerContext {

388

/**

389

* Gets the SQL statement being executed

390

* @return SQL string with parameter placeholders

391

*/

392

String getSQL();

393

394

/**

395

* Gets the parameter bindings for the SQL

396

* @return List of parameter values in order

397

*/

398

List<Object> getBindings();

399

400

/**

401

* Gets execution metadata

402

* @return Map of metadata key-value pairs

403

*/

404

Map<String, Object> getData();

405

406

/**

407

* Gets the entity being operated on (for DML operations)

408

* @return Entity path or null for queries

409

*/

410

RelationalPath<?> getEntity();

411

}

412

413

/**

414

* Manages multiple listeners as a single unit

415

*/

416

public class SQLListeners implements SQLDetailedListener {

417

/**

418

* Creates listener collection from individual listeners

419

* @param listeners Individual listener instances

420

*/

421

public SQLListeners(SQLListener... listeners);

422

423

/**

424

* Adds a listener to the collection

425

* @param listener Listener to add

426

*/

427

public void add(SQLListener listener);

428

429

/**

430

* Removes a listener from the collection

431

* @param listener Listener to remove

432

*/

433

public void remove(SQLListener listener);

434

}

435

```

436

437

### Built-in Listener Implementations

438

439

Pre-built listener implementations for common use cases.

440

441

```java { .api }

442

/**

443

* Base listener implementation with no-op methods

444

*/

445

public class SQLBaseListener implements SQLListener {

446

// All methods have empty default implementations

447

}

448

449

/**

450

* Adapter implementation for selective method overriding

451

*/

452

public class SQLListenerAdapter implements SQLDetailedListener {

453

// All methods have empty default implementations

454

}

455

456

/**

457

* Automatically closes database connections after operations

458

*/

459

public class SQLCloseListener implements SQLListener {

460

public static final SQLCloseListener DEFAULT = new SQLCloseListener();

461

462

@Override

463

public void notifyQuery(SQLListenerContext context) {

464

// Closes connection if auto-close is enabled

465

}

466

}

467

468

/**

469

* Listener that doesn't close connections

470

*/

471

public class SQLNoCloseListener implements SQLListener {

472

public static final SQLNoCloseListener DEFAULT = new SQLNoCloseListener();

473

474

// No-op implementation that preserves connections

475

}

476

```

477

478

**Usage Examples:**

479

480

```java

481

// Automatic connection management

482

config.addListener(SQLCloseListener.DEFAULT);

483

484

// Custom composite listener

485

SQLListeners compositeListener = new SQLListeners(

486

new AuditingListener(),

487

new CacheClearingListener(),

488

new MetricsListener()

489

);

490

config.addListener(compositeListener);

491

492

// Conditional listener

493

SQLListener conditionalListener = new SQLBaseListener() {

494

@Override

495

public void notifyQuery(SQLListenerContext context) {

496

if (context.getSQL().contains("SELECT")) {

497

queryCache.invalidate(context.getSQL());

498

}

499

}

500

};

501

```

502

503

### Configuration Builder Pattern

504

505

Builder pattern for constructing complex configurations with multiple customizations.

506

507

```java { .api }

508

/**

509

* Builder pattern for Configuration construction

510

*/

511

public class ConfigurationBuilder {

512

/**

513

* Sets the SQL templates

514

* @param templates Database-specific templates

515

* @return Builder for method chaining

516

*/

517

public ConfigurationBuilder templates(SQLTemplates templates);

518

519

/**

520

* Sets the default schema

521

* @param schema Schema name

522

* @return Builder for method chaining

523

*/

524

public ConfigurationBuilder schema(String schema);

525

526

/**

527

* Sets the name mapping strategy

528

* @param nameMapping Name mapping implementation

529

* @return Builder for method chaining

530

*/

531

public ConfigurationBuilder nameMapping(NameMapping nameMapping);

532

533

/**

534

* Adds a SQL listener

535

* @param listener Listener to add

536

* @return Builder for method chaining

537

*/

538

public ConfigurationBuilder listener(SQLListener listener);

539

540

/**

541

* Registers a custom type

542

* @param table Table name

543

* @param column Column name

544

* @param type Type handler

545

* @return Builder for method chaining

546

*/

547

public ConfigurationBuilder register(String table, String column, Type<?> type);

548

549

/**

550

* Builds the final configuration

551

* @return Configured Configuration instance

552

*/

553

public Configuration build();

554

}

555

```

556

557

**Usage Examples:**

558

559

```java

560

// Complex configuration using builder pattern

561

Configuration config = new ConfigurationBuilder()

562

.templates(PostgreSQLTemplates.builder().build())

563

.schema("application")

564

.nameMapping(PreConfiguredNameMapping.CAMEL_CASE_TO_LOWER_WITH_UNDERSCORES)

565

.listener(new AuditingListener())

566

.listener(new PerformanceListener())

567

.register("user", "status", new EnumByNameType<>(UserStatus.class))

568

.register("order", "amount", new MoneyType())

569

.build();

570

571

SQLQueryFactory queryFactory = new SQLQueryFactory(config, dataSource);

572

```