CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-mybatis--mybatis

SQL mapping framework that eliminates JDBC boilerplate and couples objects with stored procedures or SQL statements using XML descriptors or annotations.

Pending
Overview
Eval results
Files

type-handling.mddocs/

Type Handling

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.

Capabilities

TypeHandler Interface

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

/**
 * Handles conversion between Java types and JDBC types
 */
interface TypeHandler<T> {
    /** Set parameter value in PreparedStatement */
    void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
    
    /** Get result by column name */
    T getResult(ResultSet rs, String columnName) throws SQLException;
    
    /** Get result by column index */
    T getResult(ResultSet rs, int columnIndex) throws SQLException;
    
    /** Get result from CallableStatement */
    T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

BaseTypeHandler

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

/**
 * Base implementation for type handlers with automatic null handling
 */
abstract class BaseTypeHandler<T> implements TypeHandler<T> {
    /** Set non-null parameter value */
    public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
    
    /** Get nullable result by column name */
    public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;
    
    /** Get nullable result by column index */
    public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;
    
    /** Get nullable result from CallableStatement */
    public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;
}

Usage Examples:

// Custom type handler for converting between String and custom enum
public class StatusTypeHandler extends BaseTypeHandler<UserStatus> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.getCode());
    }

    @Override
    public UserStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String code = rs.getString(columnName);
        return code == null ? null : UserStatus.fromCode(code);
    }

    @Override
    public UserStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String code = rs.getString(columnIndex);
        return code == null ? null : UserStatus.fromCode(code);
    }

    @Override
    public UserStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String code = cs.getString(columnIndex);
        return code == null ? null : UserStatus.fromCode(code);
    }
}

// Register custom type handler
@MappedTypes(UserStatus.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StatusTypeHandler extends BaseTypeHandler<UserStatus> {
    // implementation...
}

TypeHandlerRegistry

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

/**
 * Registry for type handlers
 */
class TypeHandlerRegistry {
    /** Register type handler for Java type */
    public <T> void register(Class<T> javaType, TypeHandler<? extends T> typeHandler);
    
    /** Register type handler for JDBC type */
    public void register(JdbcType jdbcType, TypeHandler<?> handler);
    
    /** Register type handler for Java type and JDBC type combination */
    public <T> void register(Class<T> javaType, JdbcType jdbcType, TypeHandler<? extends T> typeHandler);
    
    /** Register type handler by scanning annotations */
    public void register(Class<?> typeHandlerClass);
    
    /** Register type handler instance */
    public <T> void register(TypeHandler<T> typeHandler);
    
    /** Get type handler for Java type */
    public <T> TypeHandler<T> getTypeHandler(Class<T> type);
    
    /** Get type handler for Java type and JDBC type */
    public <T> TypeHandler<T> getTypeHandler(Class<T> type, JdbcType jdbcType);
    
    /** Get type handler for JDBC type */
    public TypeHandler<?> getTypeHandler(JdbcType jdbcType);
    
    /** Get unknown type handler */
    public TypeHandler<Object> getUnknownTypeHandler();
}

Built-in Type Handlers

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

String Type Handlers

// String ↔ VARCHAR
class StringTypeHandler extends BaseTypeHandler<String>;

// String ↔ CLOB
class ClobTypeHandler extends BaseTypeHandler<String>;

// String ↔ NCLOB  
class NClobTypeHandler extends BaseTypeHandler<String>;

Numeric Type Handlers

// Boolean ↔ BOOLEAN
class BooleanTypeHandler extends BaseTypeHandler<Boolean>;

// Byte ↔ TINYINT
class ByteTypeHandler extends BaseTypeHandler<Byte>;

// Short ↔ SMALLINT
class ShortTypeHandler extends BaseTypeHandler<Short>;

// Integer ↔ INTEGER
class IntegerTypeHandler extends BaseTypeHandler<Integer>;

// Long ↔ BIGINT
class LongTypeHandler extends BaseTypeHandler<Long>;

// Float ↔ FLOAT
class FloatTypeHandler extends BaseTypeHandler<Float>;

// Double ↔ DOUBLE
class DoubleTypeHandler extends BaseTypeHandler<Double>;

// BigDecimal ↔ DECIMAL
class BigDecimalTypeHandler extends BaseTypeHandler<BigDecimal>;

// BigInteger ↔ BIGINT
class BigIntegerTypeHandler extends BaseTypeHandler<BigInteger>;

Date/Time Type Handlers

// java.util.Date ↔ DATE
class DateTypeHandler extends BaseTypeHandler<Date>;

// java.util.Date ↔ TIME
class TimeTypeHandler extends BaseTypeHandler<Date>;

// java.util.Date ↔ TIMESTAMP
class TimestampTypeHandler extends BaseTypeHandler<Date>;

// java.sql.Date ↔ DATE
class SqlDateTypeHandler extends BaseTypeHandler<java.sql.Date>;

// java.sql.Time ↔ TIME
class SqlTimeTypeHandler extends BaseTypeHandler<java.sql.Time>;

// java.sql.Timestamp ↔ TIMESTAMP
class SqlTimestampTypeHandler extends BaseTypeHandler<java.sql.Timestamp>;

Java 8 Time API Handlers

// LocalDate ↔ DATE
class LocalDateTypeHandler extends BaseTypeHandler<LocalDate>;

// LocalTime ↔ TIME
class LocalTimeTypeHandler extends BaseTypeHandler<LocalTime>;

// LocalDateTime ↔ TIMESTAMP
class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime>;

// OffsetDateTime ↔ TIMESTAMP
class OffsetDateTimeTypeHandler extends BaseTypeHandler<OffsetDateTime>;

// ZonedDateTime ↔ TIMESTAMP
class ZonedDateTimeTypeHandler extends BaseTypeHandler<ZonedDateTime>;

// Instant ↔ TIMESTAMP
class InstantTypeHandler extends BaseTypeHandler<Instant>;

// Month ↔ INTEGER
class MonthTypeHandler extends BaseTypeHandler<Month>;

// Year ↔ INTEGER
class YearTypeHandler extends BaseTypeHandler<Year>;

// YearMonth ↔ VARCHAR
class YearMonthTypeHandler extends BaseTypeHandler<YearMonth>;

Binary Type Handlers

// byte[] ↔ BLOB
class ByteArrayTypeHandler extends BaseTypeHandler<byte[]>;

// Blob ↔ BLOB
class BlobTypeHandler extends BaseTypeHandler<Blob>;

// InputStream ↔ BLOB
class BlobInputStreamTypeHandler extends BaseTypeHandler<InputStream>;

Enum Type Handlers

// Enum ↔ VARCHAR (using enum name)
class EnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E>;

// Enum ↔ INTEGER (using enum ordinal)
class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E>;

Usage Examples:

// Enum type handlers in mapper configuration
public interface UserMapper {
    @Select("SELECT * FROM users WHERE status = #{status}")
    @Results({
        @Result(property = "status", column = "status", 
                javaType = UserStatus.class, 
                typeHandler = EnumTypeHandler.class)
    })
    List<User> findByStatus(@Param("status") UserStatus status);
}

// Using custom type handler
public interface OrderMapper {
    @Select("SELECT * FROM orders WHERE id = #{id}")
    @Results({
        @Result(property = "amount", column = "amount_cents",
                javaType = BigDecimal.class,
                typeHandler = CentsToDecimalTypeHandler.class)
    })
    Order findById(@Param("id") Long id);
}

Type Handler Configuration Annotations

@MappedTypes

Specifies which Java types a type handler can process.

/**
 * Specifies Java types handled by this type handler
 */
@interface MappedTypes {
    /** Java types this handler supports */
    Class<?>[] value();
}

@MappedJdbcTypes

Specifies which JDBC types a type handler can process.

/**
 * Specifies JDBC types handled by this type handler
 */
@interface MappedJdbcTypes {
    /** JDBC types this handler supports */
    JdbcType[] value();
    
    /** Whether to include null handling */
    boolean includeNullJdbcType() default false;
}

Usage Examples:

@MappedTypes(UserStatus.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class UserStatusTypeHandler extends BaseTypeHandler<UserStatus> {
    // Custom enum type handler implementation
    
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.name());
    }
    
    @Override
    public UserStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        return value == null ? null : UserStatus.valueOf(value);
    }
    
    // ... other methods
}

// Multiple type mapping
@MappedTypes({Address.class, ContactInfo.class})
@MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CLOB})
public class JsonTypeHandler extends BaseTypeHandler<Object> {
    // JSON serialization type handler
}

JdbcType Enumeration

Comprehensive enumeration of JDBC types for type handler mapping.

/**
 * JDBC type constants for type handler mapping
 */
enum JdbcType {
    // Numeric types
    TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC,
    
    // Character types
    CHAR, VARCHAR, LONGVARCHAR, NCHAR, NVARCHAR, LONGNVARCHAR,
    
    // Binary types
    BINARY, VARBINARY, LONGVARBINARY, BLOB,
    
    // Date/time types
    DATE, TIME, TIMESTAMP, TIME_WITH_TIMEZONE, TIMESTAMP_WITH_TIMEZONE,
    
    // Other types
    BOOLEAN, BIT, NULL, OTHER, UNDEFINED, CURSOR, ARRAY, STRUCT, REF,
    CLOB, NCLOB, SQLXML, DATETIMEOFFSET;
}

Custom Type Handler Examples

JSON Type Handler

@MappedTypes(Object.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler extends BaseTypeHandler<Object> {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        try {
            ps.setString(i, objectMapper.writeValueAsString(parameter));
        } catch (JsonProcessingException e) {
            throw new SQLException("Error converting object to JSON", e);
        }
    }
    
    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        return parseJson(json);
    }
    
    private Object parseJson(String json) throws SQLException {
        if (json == null || json.trim().isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(json, Object.class);
        } catch (JsonProcessingException e) {
            throw new SQLException("Error parsing JSON", e);
        }
    }
    
    // ... other methods
}

Encrypted String Type Handler

@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptedStringTypeHandler extends BaseTypeHandler<String> {
    private final EncryptionService encryptionService;
    
    public EncryptedStringTypeHandler() {
        this.encryptionService = new EncryptionService();
    }
    
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        String encrypted = encryptionService.encrypt(parameter);
        ps.setString(i, encrypted);
    }
    
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String encrypted = rs.getString(columnName);
        return encrypted == null ? null : encryptionService.decrypt(encrypted);
    }
    
    // ... other methods
}

Types

/**
 * Type alias registry for mapping short names to full class names
 */
class TypeAliasRegistry {
    /** Register type alias */
    public void registerAlias(String alias, Class<?> value);
    
    /** Register type alias with class name */
    public void registerAlias(String alias, String value);
    
    /** Register aliases for a package */
    public void registerAliases(String packageName);
    
    /** Resolve type alias to class */
    public <T> Class<T> resolveAlias(String string);
}

/**
 * Exception thrown during type handling operations
 */
class TypeException extends PersistenceException {
    public TypeException(String message);
    public TypeException(String message, Throwable cause);
}

Install with Tessl CLI

npx tessl i tessl/maven-org-mybatis--mybatis

docs

cache-system.md

index.md

mapping-annotations.md

plugin-system.md

session-management.md

transaction-management.md

type-handling.md

tile.json