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

type-system.mddocs/

0

# Type System

1

2

QueryDSL SQL provides a comprehensive type mapping system between Java and SQL types with support for custom types, automatic conversion, and database-specific type handling across 50+ built-in type handlers.

3

4

## Capabilities

5

6

### Core Type Interface

7

8

Base interface for all type handlers that define how Java objects are converted to and from SQL values.

9

10

```java { .api }

11

/**

12

* Core interface for type conversion between Java and SQL

13

* @param <T> Java type being handled

14

*/

15

public interface Type<T> {

16

/**

17

* Retrieves value from ResultSet and converts to Java type

18

* @param rs ResultSet containing the data

19

* @param startIndex Starting column index (1-based)

20

* @return Converted Java object

21

* @throws SQLException if database access error occurs

22

*/

23

T getValue(ResultSet rs, int startIndex) throws SQLException;

24

25

/**

26

* Sets value in PreparedStatement after converting from Java type

27

* @param st PreparedStatement to set value in

28

* @param startIndex Starting parameter index (1-based)

29

* @param value Java object to convert and set

30

* @throws SQLException if database access error occurs

31

*/

32

void setValue(PreparedStatement st, int startIndex, T value) throws SQLException;

33

34

/**

35

* Gets the JDBC type codes this handler supports

36

* @return Array of JDBC type constants

37

*/

38

int[] getSQLTypes();

39

40

/**

41

* Gets the Java class this type handler manages

42

* @return Java class

43

*/

44

Class<T> getReturnedClass();

45

46

/**

47

* Creates a literal representation for SQL generation

48

* @param value Java value to convert to SQL literal

49

* @return SQL literal string

50

*/

51

String getLiteral(T value);

52

}

53

```

54

55

### Abstract Base Types

56

57

Base implementations providing common functionality for type handlers.

58

59

```java { .api }

60

/**

61

* Abstract base class for all type implementations

62

* @param <T> Java type being handled

63

*/

64

public abstract class AbstractType<T> implements Type<T> {

65

/**

66

* Creates type handler for specified Java class

67

* @param type Java class this handler manages

68

*/

69

protected AbstractType(Class<T> type);

70

71

/**

72

* Gets null-safe value from ResultSet

73

* @param rs ResultSet to read from

74

* @param startIndex Column index

75

* @return Value or null if SQL NULL

76

*/

77

protected T getNullableValue(ResultSet rs, int startIndex) throws SQLException;

78

}

79

80

/**

81

* Base class for date/time type handlers

82

* @param <T> Date/time type

83

*/

84

public abstract class AbstractDateTimeType<T> extends AbstractType<T>;

85

86

/**

87

* Base class for JSR-310 (java.time) type handlers

88

* @param <T> java.time type

89

*/

90

public abstract class AbstractJSR310DateTimeType<T> extends AbstractDateTimeType<T>;

91

```

92

93

### Primitive and Basic Types

94

95

Type handlers for Java primitive types and their wrapper classes.

96

97

```java { .api }

98

/**

99

* String type handler

100

*/

101

public class StringType extends AbstractType<String>;

102

103

/**

104

* String type that handles SQL NULL as empty string

105

*/

106

public class StringAsObjectType extends AbstractType<String>;

107

108

/**

109

* Integer type handler

110

*/

111

public class IntegerType extends AbstractType<Integer>;

112

113

/**

114

* Long type handler

115

*/

116

public class LongType extends AbstractType<Long>;

117

118

/**

119

* Double type handler

120

*/

121

public class DoubleType extends AbstractType<Double>;

122

123

/**

124

* Boolean type handler

125

*/

126

public class BooleanType extends AbstractType<Boolean>;

127

128

/**

129

* Character type handler

130

*/

131

public class CharacterType extends AbstractType<Character>;

132

133

/**

134

* Byte type handler

135

*/

136

public class ByteType extends AbstractType<Byte>;

137

138

/**

139

* Short type handler

140

*/

141

public class ShortType extends AbstractType<Short>;

142

143

/**

144

* Float type handler

145

*/

146

public class FloatType extends AbstractType<Float>;

147

```

148

149

**Usage Examples:**

150

151

```java

152

// Register custom type in configuration

153

Configuration config = new Configuration(templates);

154

config.register(new StringType());

155

config.register(new IntegerType());

156

157

// Type registration is typically automatic for standard types

158

SQLQueryFactory queryFactory = new SQLQueryFactory(config, dataSource);

159

160

// Types are used automatically during query execution

161

List<String> names = queryFactory

162

.select(qUser.name) // StringType used automatically

163

.from(qUser)

164

.fetch();

165

```

166

167

### Numeric Types

168

169

Specialized type handlers for high-precision numeric types.

170

171

```java { .api }

172

/**

173

* BigDecimal type handler for precise decimal arithmetic

174

*/

175

public class BigDecimalType extends AbstractType<BigDecimal>;

176

177

/**

178

* BigDecimal type that maps to DOUBLE SQL type

179

*/

180

public class BigDecimalAsDoubleType extends AbstractType<BigDecimal>;

181

182

/**

183

* BigInteger type handler for arbitrary-precision integers

184

*/

185

public class BigIntegerType extends AbstractType<BigInteger>;

186

187

/**

188

* BigInteger type that maps to BIGINT SQL type

189

*/

190

public class BigIntegerAsLongType extends AbstractType<BigInteger>;

191

```

192

193

**Usage Examples:**

194

195

```java

196

// Working with high-precision numbers

197

List<BigDecimal> prices = queryFactory

198

.select(qProduct.price) // BigDecimalType used for DECIMAL columns

199

.from(qProduct)

200

.fetch();

201

202

// Custom precision handling

203

Configuration config = new Configuration(templates);

204

config.register("product", "price", new BigDecimalType());

205

```

206

207

### Date and Time Types

208

209

Type handlers for various date and time representations.

210

211

```java { .api }

212

/**

213

* java.sql.Date type handler

214

*/

215

public class DateType extends AbstractDateTimeType<java.sql.Date>;

216

217

/**

218

* java.sql.Time type handler

219

*/

220

public class TimeType extends AbstractDateTimeType<java.sql.Time>;

221

222

/**

223

* java.sql.Timestamp type handler

224

*/

225

public class TimestampType extends AbstractDateTimeType<java.sql.Timestamp>;

226

227

/**

228

* java.util.Date type handler

229

*/

230

public class UtilDateType extends AbstractDateTimeType<java.util.Date>;

231

232

/**

233

* java.util.Calendar type handler

234

*/

235

public class CalendarType extends AbstractDateTimeType<Calendar>;

236

```

237

238

### JSR-310 (java.time) Types

239

240

Modern Java time API type handlers with timezone support.

241

242

```java { .api }

243

/**

244

* LocalDate type handler

245

*/

246

public class JSR310LocalDateType extends AbstractJSR310DateTimeType<LocalDate>;

247

248

/**

249

* LocalTime type handler

250

*/

251

public class JSR310LocalTimeType extends AbstractJSR310DateTimeType<LocalTime>;

252

253

/**

254

* LocalDateTime type handler

255

*/

256

public class JSR310LocalDateTimeType extends AbstractJSR310DateTimeType<LocalDateTime>;

257

258

/**

259

* OffsetTime type handler with timezone offset

260

*/

261

public class JSR310OffsetTimeType extends AbstractJSR310DateTimeType<OffsetTime>;

262

263

/**

264

* OffsetDateTime type handler with timezone offset

265

*/

266

public class JSR310OffsetDateTimeType extends AbstractJSR310DateTimeType<OffsetDateTime>;

267

268

/**

269

* ZonedDateTime type handler with full timezone support

270

*/

271

public class JSR310ZonedDateTimeType extends AbstractJSR310DateTimeType<ZonedDateTime>;

272

273

/**

274

* Instant type handler for timestamps

275

*/

276

public class JSR310InstantType extends AbstractJSR310DateTimeType<Instant>;

277

```

278

279

**Usage Examples:**

280

281

```java

282

// Modern time API usage

283

List<LocalDateTime> createdTimes = queryFactory

284

.select(qOrder.createdAt) // JSR310LocalDateTimeType used automatically

285

.from(qOrder)

286

.fetch();

287

288

// Timezone-aware queries

289

List<ZonedDateTime> zonedTimes = queryFactory

290

.select(qEvent.scheduledAt) // JSR310ZonedDateTimeType for timezone data

291

.from(qEvent)

292

.fetch();

293

```

294

295

### Binary and LOB Types

296

297

Type handlers for binary data and large objects.

298

299

```java { .api }

300

/**

301

* byte[] type handler for binary data

302

*/

303

public class BytesType extends AbstractType<byte[]>;

304

305

/**

306

* byte[] type handler for LONGVARBINARY columns

307

*/

308

public class LongVarBinaryBytesType extends AbstractType<byte[]>;

309

310

/**

311

* java.sql.Blob type handler for binary large objects

312

*/

313

public class BlobType extends AbstractType<Blob>;

314

315

/**

316

* java.sql.Clob type handler for character large objects

317

*/

318

public class ClobType extends AbstractType<Clob>;

319

320

/**

321

* InputStream type handler for streaming binary data

322

*/

323

public class InputStreamType extends AbstractType<InputStream>;

324

```

325

326

**Usage Examples:**

327

328

```java

329

// Binary data handling

330

byte[] imageData = queryFactory

331

.select(qDocument.content) // BytesType for VARBINARY columns

332

.from(qDocument)

333

.where(qDocument.id.eq(docId))

334

.fetchOne();

335

336

// Large object streaming

337

InputStream stream = queryFactory

338

.select(qDocument.largeContent) // InputStreamType for streaming

339

.from(qDocument)

340

.where(qDocument.id.eq(docId))

341

.fetchOne();

342

```

343

344

### Enum Types

345

346

Type handlers for Java enums with different storage strategies.

347

348

```java { .api }

349

/**

350

* Enum type handler that stores enum values by name (toString)

351

* @param <T> Enum type

352

*/

353

public class EnumByNameType<T extends Enum<T>> extends AbstractType<T> {

354

public EnumByNameType(Class<T> enumClass);

355

}

356

357

/**

358

* Enum type handler that stores enum values by ordinal (int)

359

* @param <T> Enum type

360

*/

361

public class EnumByOrdinalType<T extends Enum<T>> extends AbstractType<T> {

362

public EnumByOrdinalType(Class<T> enumClass);

363

}

364

365

/**

366

* Enum type handler that stores enum as generic object

367

* @param <T> Enum type

368

*/

369

public class EnumAsObjectType<T extends Enum<T>> extends AbstractType<T> {

370

public EnumAsObjectType(Class<T> enumClass);

371

}

372

```

373

374

**Usage Examples:**

375

376

```java

377

// Enum by name storage

378

public enum UserStatus { ACTIVE, INACTIVE, SUSPENDED }

379

380

Configuration config = new Configuration(templates);

381

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

382

383

// Enum by ordinal storage (more efficient)

384

config.register("user", "priority", new EnumByOrdinalType<>(Priority.class));

385

386

List<UserStatus> statuses = queryFactory

387

.select(qUser.status)

388

.from(qUser)

389

.fetch();

390

```

391

392

### Boolean Conversion Types

393

394

Specialized boolean type handlers for databases that don't have native boolean support.

395

396

```java { .api }

397

/**

398

* Boolean type that stores as 'T'/'F' characters

399

*/

400

public class TrueFalseType extends AbstractType<Boolean>;

401

402

/**

403

* Boolean type that stores as 'Y'/'N' characters

404

*/

405

public class YesNoType extends AbstractType<Boolean>;

406

407

/**

408

* Boolean type that stores as 1/0 integers

409

*/

410

public class NumericBooleanType extends AbstractType<Boolean>;

411

```

412

413

**Usage Examples:**

414

415

```java

416

// Configure boolean storage for legacy databases

417

Configuration config = new Configuration(templates);

418

config.register("user", "active", new YesNoType()); // Store as Y/N

419

config.register("user", "verified", new TrueFalseType()); // Store as T/F

420

config.register("user", "premium", new NumericBooleanType()); // Store as 1/0

421

422

List<Boolean> activeFlags = queryFactory

423

.select(qUser.active) // Automatically converts Y/N to Boolean

424

.from(qUser)

425

.fetch();

426

```

427

428

### Array Types

429

430

Type handler for SQL array types with generic element type support.

431

432

```java { .api }

433

/**

434

* Generic array type handler for SQL ARRAY columns

435

* @param <T> Element type of the array

436

*/

437

public class ArrayType<T> extends AbstractType<T[]> {

438

/**

439

* Creates array type handler

440

* @param elementType Type handler for array elements

441

* @param javaType Java array class

442

*/

443

public ArrayType(Type<T> elementType, Class<T[]> javaType);

444

}

445

```

446

447

**Usage Examples:**

448

449

```java

450

// PostgreSQL array support

451

Configuration config = new Configuration(PostgreSQLTemplates.builder().build());

452

config.register("user", "tags", new ArrayType<>(new StringType(), String[].class));

453

454

// Query array columns

455

List<String[]> userTags = queryFactory

456

.select(qUser.tags) // Returns String[] from PostgreSQL text[]

457

.from(qUser)

458

.fetch();

459

460

// Array operations in queries

461

List<User> users = queryFactory

462

.selectFrom(qUser)

463

.where(qUser.tags.contains("vip")) // PostgreSQL array contains operator

464

.fetch();

465

```

466

467

### Specialized Types

468

469

Type handlers for specialized data types like UUID, URL, XML, and others.

470

471

```java { .api }

472

/**

473

* java.util.UUID type handler

474

*/

475

public class UtilUUIDType extends AbstractType<UUID>;

476

477

/**

478

* java.net.URL type handler

479

*/

480

public class URLType extends AbstractType<URL>;

481

482

/**

483

* java.util.Locale type handler

484

*/

485

public class LocaleType extends AbstractType<Locale>;

486

487

/**

488

* java.util.Currency type handler

489

*/

490

public class CurrencyType extends AbstractType<Currency>;

491

492

/**

493

* java.sql.SQLXML type handler

494

*/

495

public class SQLXMLType extends AbstractType<SQLXML>;

496

497

/**

498

* XML data stored as String

499

*/

500

public class XMLAsStringType extends AbstractType<String>;

501

502

/**

503

* Generic Object type handler

504

*/

505

public class ObjectType extends AbstractType<Object>;

506

```

507

508

**Usage Examples:**

509

510

```java

511

// UUID primary keys

512

Configuration config = new Configuration(templates);

513

config.register("user", "id", new UtilUUIDType());

514

515

List<UUID> userIds = queryFactory

516

.select(qUser.id) // UUID type conversion

517

.from(qUser)

518

.fetch();

519

520

// XML data handling

521

config.register("document", "content", new XMLAsStringType());

522

523

List<String> xmlContent = queryFactory

524

.select(qDocument.content) // XML stored as String

525

.from(qDocument)

526

.fetch();

527

```

528

529

### Custom Type Creation

530

531

Framework for creating custom type handlers for application-specific data types.

532

533

```java { .api }

534

/**

535

* Interface for null value representation in type system

536

*/

537

public class Null {

538

public static final Object DEFAULT = new Object();

539

}

540

541

/**

542

* Base class for creating custom type handlers

543

* @param <T> Java type to handle

544

*/

545

public abstract class AbstractType<T> implements Type<T> {

546

/**

547

* Template method for handling null values

548

* @param rs ResultSet to read from

549

* @param startIndex Column index

550

* @return Null-safe value

551

*/

552

protected T getNullableValue(ResultSet rs, int startIndex) throws SQLException;

553

554

/**

555

* Template method for setting null values

556

* @param st PreparedStatement to write to

557

* @param startIndex Parameter index

558

* @param value Value to set (may be null)

559

*/

560

protected void setNullableValue(PreparedStatement st, int startIndex, T value) throws SQLException;

561

}

562

```

563

564

**Usage Examples:**

565

566

```java

567

// Custom type for application-specific data

568

public class MoneyType extends AbstractType<Money> {

569

public MoneyType() {

570

super(Money.class);

571

}

572

573

@Override

574

public Money getValue(ResultSet rs, int startIndex) throws SQLException {

575

BigDecimal amount = rs.getBigDecimal(startIndex);

576

String currency = rs.getString(startIndex + 1);

577

return amount != null ? new Money(amount, currency) : null;

578

}

579

580

@Override

581

public void setValue(PreparedStatement st, int startIndex, Money value) throws SQLException {

582

if (value != null) {

583

st.setBigDecimal(startIndex, value.getAmount());

584

st.setString(startIndex + 1, value.getCurrency());

585

} else {

586

st.setNull(startIndex, Types.DECIMAL);

587

st.setNull(startIndex + 1, Types.VARCHAR);

588

}

589

}

590

591

@Override

592

public int[] getSQLTypes() {

593

return new int[] { Types.DECIMAL, Types.VARCHAR };

594

}

595

}

596

597

// Register custom type

598

Configuration config = new Configuration(templates);

599

config.register("order", "total", new MoneyType());

600

601

// Use custom type in queries

602

List<Money> orderTotals = queryFactory

603

.select(qOrder.total) // MoneyType handles conversion automatically

604

.from(qOrder)

605

.fetch();

606

```