or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-system.mdindex.mdmapping-annotations.mdplugin-system.mdsession-management.mdtransaction-management.mdtype-handling.md

type-handling.mddocs/

0

# Type Handling

1

2

Comprehensive type conversion system between Java types and JDBC types. MyBatis includes extensive built-in type handlers and supports custom type handlers for specialized conversions.

3

4

## Capabilities

5

6

### TypeHandler Interface

7

8

Core interface for handling conversions between Java types and JDBC types.

9

10

```java { .api }

11

/**

12

* Handles conversion between Java types and JDBC types

13

*/

14

interface TypeHandler<T> {

15

/** Set parameter value in PreparedStatement */

16

void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

17

18

/** Get result by column name */

19

T getResult(ResultSet rs, String columnName) throws SQLException;

20

21

/** Get result by column index */

22

T getResult(ResultSet rs, int columnIndex) throws SQLException;

23

24

/** Get result from CallableStatement */

25

T getResult(CallableStatement cs, int columnIndex) throws SQLException;

26

}

27

```

28

29

### BaseTypeHandler

30

31

Abstract base class that simplifies creating custom type handlers by handling null values automatically.

32

33

```java { .api }

34

/**

35

* Base implementation for type handlers with automatic null handling

36

*/

37

abstract class BaseTypeHandler<T> implements TypeHandler<T> {

38

/** Set non-null parameter value */

39

public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

40

41

/** Get nullable result by column name */

42

public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

43

44

/** Get nullable result by column index */

45

public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

46

47

/** Get nullable result from CallableStatement */

48

public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

49

}

50

```

51

52

**Usage Examples:**

53

54

```java

55

// Custom type handler for converting between String and custom enum

56

public class StatusTypeHandler extends BaseTypeHandler<UserStatus> {

57

@Override

58

public void setNonNullParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException {

59

ps.setString(i, parameter.getCode());

60

}

61

62

@Override

63

public UserStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {

64

String code = rs.getString(columnName);

65

return code == null ? null : UserStatus.fromCode(code);

66

}

67

68

@Override

69

public UserStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

70

String code = rs.getString(columnIndex);

71

return code == null ? null : UserStatus.fromCode(code);

72

}

73

74

@Override

75

public UserStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

76

String code = cs.getString(columnIndex);

77

return code == null ? null : UserStatus.fromCode(code);

78

}

79

}

80

81

// Register custom type handler

82

@MappedTypes(UserStatus.class)

83

@MappedJdbcTypes(JdbcType.VARCHAR)

84

public class StatusTypeHandler extends BaseTypeHandler<UserStatus> {

85

// implementation...

86

}

87

```

88

89

### TypeHandlerRegistry

90

91

Registry for managing type handlers and their associations with Java and JDBC types.

92

93

```java { .api }

94

/**

95

* Registry for type handlers

96

*/

97

class TypeHandlerRegistry {

98

/** Register type handler for Java type */

99

public <T> void register(Class<T> javaType, TypeHandler<? extends T> typeHandler);

100

101

/** Register type handler for JDBC type */

102

public void register(JdbcType jdbcType, TypeHandler<?> handler);

103

104

/** Register type handler for Java type and JDBC type combination */

105

public <T> void register(Class<T> javaType, JdbcType jdbcType, TypeHandler<? extends T> typeHandler);

106

107

/** Register type handler by scanning annotations */

108

public void register(Class<?> typeHandlerClass);

109

110

/** Register type handler instance */

111

public <T> void register(TypeHandler<T> typeHandler);

112

113

/** Get type handler for Java type */

114

public <T> TypeHandler<T> getTypeHandler(Class<T> type);

115

116

/** Get type handler for Java type and JDBC type */

117

public <T> TypeHandler<T> getTypeHandler(Class<T> type, JdbcType jdbcType);

118

119

/** Get type handler for JDBC type */

120

public TypeHandler<?> getTypeHandler(JdbcType jdbcType);

121

122

/** Get unknown type handler */

123

public TypeHandler<Object> getUnknownTypeHandler();

124

}

125

```

126

127

### Built-in Type Handlers

128

129

MyBatis includes comprehensive built-in type handlers for standard Java types.

130

131

#### String Type Handlers

132

133

```java { .api }

134

// String ↔ VARCHAR

135

class StringTypeHandler extends BaseTypeHandler<String>;

136

137

// String ↔ CLOB

138

class ClobTypeHandler extends BaseTypeHandler<String>;

139

140

// String ↔ NCLOB

141

class NClobTypeHandler extends BaseTypeHandler<String>;

142

```

143

144

#### Numeric Type Handlers

145

146

```java { .api }

147

// Boolean ↔ BOOLEAN

148

class BooleanTypeHandler extends BaseTypeHandler<Boolean>;

149

150

// Byte ↔ TINYINT

151

class ByteTypeHandler extends BaseTypeHandler<Byte>;

152

153

// Short ↔ SMALLINT

154

class ShortTypeHandler extends BaseTypeHandler<Short>;

155

156

// Integer ↔ INTEGER

157

class IntegerTypeHandler extends BaseTypeHandler<Integer>;

158

159

// Long ↔ BIGINT

160

class LongTypeHandler extends BaseTypeHandler<Long>;

161

162

// Float ↔ FLOAT

163

class FloatTypeHandler extends BaseTypeHandler<Float>;

164

165

// Double ↔ DOUBLE

166

class DoubleTypeHandler extends BaseTypeHandler<Double>;

167

168

// BigDecimal ↔ DECIMAL

169

class BigDecimalTypeHandler extends BaseTypeHandler<BigDecimal>;

170

171

// BigInteger ↔ BIGINT

172

class BigIntegerTypeHandler extends BaseTypeHandler<BigInteger>;

173

```

174

175

#### Date/Time Type Handlers

176

177

```java { .api }

178

// java.util.Date ↔ DATE

179

class DateTypeHandler extends BaseTypeHandler<Date>;

180

181

// java.util.Date ↔ TIME

182

class TimeTypeHandler extends BaseTypeHandler<Date>;

183

184

// java.util.Date ↔ TIMESTAMP

185

class TimestampTypeHandler extends BaseTypeHandler<Date>;

186

187

// java.sql.Date ↔ DATE

188

class SqlDateTypeHandler extends BaseTypeHandler<java.sql.Date>;

189

190

// java.sql.Time ↔ TIME

191

class SqlTimeTypeHandler extends BaseTypeHandler<java.sql.Time>;

192

193

// java.sql.Timestamp ↔ TIMESTAMP

194

class SqlTimestampTypeHandler extends BaseTypeHandler<java.sql.Timestamp>;

195

```

196

197

#### Java 8 Time API Handlers

198

199

```java { .api }

200

// LocalDate ↔ DATE

201

class LocalDateTypeHandler extends BaseTypeHandler<LocalDate>;

202

203

// LocalTime ↔ TIME

204

class LocalTimeTypeHandler extends BaseTypeHandler<LocalTime>;

205

206

// LocalDateTime ↔ TIMESTAMP

207

class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime>;

208

209

// OffsetDateTime ↔ TIMESTAMP

210

class OffsetDateTimeTypeHandler extends BaseTypeHandler<OffsetDateTime>;

211

212

// ZonedDateTime ↔ TIMESTAMP

213

class ZonedDateTimeTypeHandler extends BaseTypeHandler<ZonedDateTime>;

214

215

// Instant ↔ TIMESTAMP

216

class InstantTypeHandler extends BaseTypeHandler<Instant>;

217

218

// Month ↔ INTEGER

219

class MonthTypeHandler extends BaseTypeHandler<Month>;

220

221

// Year ↔ INTEGER

222

class YearTypeHandler extends BaseTypeHandler<Year>;

223

224

// YearMonth ↔ VARCHAR

225

class YearMonthTypeHandler extends BaseTypeHandler<YearMonth>;

226

```

227

228

#### Binary Type Handlers

229

230

```java { .api }

231

// byte[] ↔ BLOB

232

class ByteArrayTypeHandler extends BaseTypeHandler<byte[]>;

233

234

// Blob ↔ BLOB

235

class BlobTypeHandler extends BaseTypeHandler<Blob>;

236

237

// InputStream ↔ BLOB

238

class BlobInputStreamTypeHandler extends BaseTypeHandler<InputStream>;

239

```

240

241

#### Enum Type Handlers

242

243

```java { .api }

244

// Enum ↔ VARCHAR (using enum name)

245

class EnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E>;

246

247

// Enum ↔ INTEGER (using enum ordinal)

248

class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E>;

249

```

250

251

**Usage Examples:**

252

253

```java

254

// Enum type handlers in mapper configuration

255

public interface UserMapper {

256

@Select("SELECT * FROM users WHERE status = #{status}")

257

@Results({

258

@Result(property = "status", column = "status",

259

javaType = UserStatus.class,

260

typeHandler = EnumTypeHandler.class)

261

})

262

List<User> findByStatus(@Param("status") UserStatus status);

263

}

264

265

// Using custom type handler

266

public interface OrderMapper {

267

@Select("SELECT * FROM orders WHERE id = #{id}")

268

@Results({

269

@Result(property = "amount", column = "amount_cents",

270

javaType = BigDecimal.class,

271

typeHandler = CentsToDecimalTypeHandler.class)

272

})

273

Order findById(@Param("id") Long id);

274

}

275

```

276

277

### Type Handler Configuration Annotations

278

279

#### @MappedTypes

280

281

Specifies which Java types a type handler can process.

282

283

```java { .api }

284

/**

285

* Specifies Java types handled by this type handler

286

*/

287

@interface MappedTypes {

288

/** Java types this handler supports */

289

Class<?>[] value();

290

}

291

```

292

293

#### @MappedJdbcTypes

294

295

Specifies which JDBC types a type handler can process.

296

297

```java { .api }

298

/**

299

* Specifies JDBC types handled by this type handler

300

*/

301

@interface MappedJdbcTypes {

302

/** JDBC types this handler supports */

303

JdbcType[] value();

304

305

/** Whether to include null handling */

306

boolean includeNullJdbcType() default false;

307

}

308

```

309

310

**Usage Examples:**

311

312

```java

313

@MappedTypes(UserStatus.class)

314

@MappedJdbcTypes(JdbcType.VARCHAR)

315

public class UserStatusTypeHandler extends BaseTypeHandler<UserStatus> {

316

// Custom enum type handler implementation

317

318

@Override

319

public void setNonNullParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException {

320

ps.setString(i, parameter.name());

321

}

322

323

@Override

324

public UserStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {

325

String value = rs.getString(columnName);

326

return value == null ? null : UserStatus.valueOf(value);

327

}

328

329

// ... other methods

330

}

331

332

// Multiple type mapping

333

@MappedTypes({Address.class, ContactInfo.class})

334

@MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CLOB})

335

public class JsonTypeHandler extends BaseTypeHandler<Object> {

336

// JSON serialization type handler

337

}

338

```

339

340

### JdbcType Enumeration

341

342

Comprehensive enumeration of JDBC types for type handler mapping.

343

344

```java { .api }

345

/**

346

* JDBC type constants for type handler mapping

347

*/

348

enum JdbcType {

349

// Numeric types

350

TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC,

351

352

// Character types

353

CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR, LONGNVARCHAR,

354

355

// Binary types

356

BINARY, VARBINARY, LONGVARBINARY, BLOB,

357

358

// Date/time types

359

DATE, TIME, TIMESTAMP, TIME_WITH_TIMEZONE, TIMESTAMP_WITH_TIMEZONE,

360

361

// Other types

362

BOOLEAN, BIT, NULL, OTHER, UNDEFINED, CURSOR, ARRAY, STRUCT, REF,

363

CLOB, NCLOB, SQLXML, DATETIMEOFFSET;

364

}

365

```

366

367

### Custom Type Handler Examples

368

369

#### JSON Type Handler

370

371

```java

372

@MappedTypes(Object.class)

373

@MappedJdbcTypes(JdbcType.VARCHAR)

374

public class JsonTypeHandler extends BaseTypeHandler<Object> {

375

private static final ObjectMapper objectMapper = new ObjectMapper();

376

377

@Override

378

public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {

379

try {

380

ps.setString(i, objectMapper.writeValueAsString(parameter));

381

} catch (JsonProcessingException e) {

382

throw new SQLException("Error converting object to JSON", e);

383

}

384

}

385

386

@Override

387

public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {

388

String json = rs.getString(columnName);

389

return parseJson(json);

390

}

391

392

private Object parseJson(String json) throws SQLException {

393

if (json == null || json.trim().isEmpty()) {

394

return null;

395

}

396

try {

397

return objectMapper.readValue(json, Object.class);

398

} catch (JsonProcessingException e) {

399

throw new SQLException("Error parsing JSON", e);

400

}

401

}

402

403

// ... other methods

404

}

405

```

406

407

#### Encrypted String Type Handler

408

409

```java

410

@MappedTypes(String.class)

411

@MappedJdbcTypes(JdbcType.VARCHAR)

412

public class EncryptedStringTypeHandler extends BaseTypeHandler<String> {

413

private final EncryptionService encryptionService;

414

415

public EncryptedStringTypeHandler() {

416

this.encryptionService = new EncryptionService();

417

}

418

419

@Override

420

public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {

421

String encrypted = encryptionService.encrypt(parameter);

422

ps.setString(i, encrypted);

423

}

424

425

@Override

426

public String getNullableResult(ResultSet rs, String columnName) throws SQLException {

427

String encrypted = rs.getString(columnName);

428

return encrypted == null ? null : encryptionService.decrypt(encrypted);

429

}

430

431

// ... other methods

432

}

433

```

434

435

## Types

436

437

```java { .api }

438

/**

439

* Type alias registry for mapping short names to full class names

440

*/

441

class TypeAliasRegistry {

442

/** Register type alias */

443

public void registerAlias(String alias, Class<?> value);

444

445

/** Register type alias with class name */

446

public void registerAlias(String alias, String value);

447

448

/** Register aliases for a package */

449

public void registerAliases(String packageName);

450

451

/** Resolve type alias to class */

452

public <T> Class<T> resolveAlias(String string);

453

}

454

455

/**

456

* Exception thrown during type handling operations

457

*/

458

class TypeException extends PersistenceException {

459

public TypeException(String message);

460

public TypeException(String message, Throwable cause);

461

}

462

```