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

mapping-annotations.mddocs/

Mapping Annotations

Annotation-based SQL mapping system that provides a declarative approach to database operations. These annotations allow you to define SQL statements directly on mapper interface methods, eliminating the need for XML configuration files.

Capabilities

Core SQL Annotations

@Select

Defines SQL SELECT statements for data retrieval operations.

/**
 * Specifies SQL SELECT statement for retrieving records
 */
@interface Select {
    /** SQL SELECT statement(s) */
    String[] value();
}

Usage Examples:

public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User findById(@Param("id") Long id);
    
    @Select("SELECT * FROM users WHERE status = #{status} ORDER BY name")
    List<User> findByStatus(@Param("status") String status);
    
    // Multi-statement select
    @Select({
        "SELECT u.*, p.name as profile_name",
        "FROM users u",
        "LEFT JOIN profiles p ON u.profile_id = p.id", 
        "WHERE u.active = #{active}"
    })
    List<UserProfile> findUsersWithProfiles(@Param("active") boolean active);
}

@Insert

Defines SQL INSERT statements for creating new records.

/**
 * Specifies SQL INSERT statement
 */
@interface Insert {
    /** SQL INSERT statement(s) */
    String[] value();
}

Usage Examples:

public interface UserMapper {
    @Insert("INSERT INTO users (name, email, status) VALUES (#{name}, #{email}, #{status})")
    int insert(User user);
    
    // Multi-statement insert
    @Insert({
        "INSERT INTO users (name, email, status)",
        "VALUES (#{name}, #{email}, #{status})"
    })
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertWithGeneratedKey(User user);
}

@Update

Defines SQL UPDATE statements for modifying existing records.

/**
 * Specifies SQL UPDATE statement
 */
@interface Update {
    /** SQL UPDATE statement(s) */
    String[] value();
}

Usage Examples:

public interface UserMapper {
    @Update("UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}")
    int update(User user);
    
    @Update("UPDATE users SET status = #{status} WHERE id = #{id}")
    int updateStatus(@Param("id") Long id, @Param("status") String status);
}

@Delete

Defines SQL DELETE statements for removing records.

/**
 * Specifies SQL DELETE statement
 */
@interface Delete {
    /** SQL DELETE statement(s) */
    String[] value();
}

Usage Examples:

public interface UserMapper {
    @Delete("DELETE FROM users WHERE id = #{id}")
    int deleteById(@Param("id") Long id);
    
    @Delete("DELETE FROM users WHERE status = #{status}")
    int deleteByStatus(@Param("status") String status);
}

Dynamic SQL Provider Annotations

For complex dynamic SQL that can't be expressed in simple annotations, use provider classes.

@SelectProvider

Uses a provider class method to generate dynamic SELECT statements.

/**
 * Specifies provider class/method for dynamic SELECT statements
 */
@interface SelectProvider {
    /** Provider class containing the SQL generation method */
    Class<?> type();
    
    /** Method name in the provider class */
    String method();
}

Usage Examples:

public interface UserMapper {
    @SelectProvider(type = UserSqlProvider.class, method = "findByConditions")
    List<User> findByConditions(UserSearchCriteria criteria);
}

public class UserSqlProvider {
    public String findByConditions(UserSearchCriteria criteria) {
        return new SQL()
            .SELECT("*")
            .FROM("users")
            .WHERE(criteria.getName() != null, "name LIKE #{name}")
            .WHERE(criteria.getStatus() != null, "status = #{status}")
            .WHERE(criteria.getMinAge() != null, "age >= #{minAge}")
            .toString();
    }
}

@InsertProvider

Uses a provider class method to generate dynamic INSERT statements.

/**
 * Specifies provider class/method for dynamic INSERT statements
 */
@interface InsertProvider {
    /** Provider class containing the SQL generation method */
    Class<?> type();
    
    /** Method name in the provider class */
    String method();
}

@UpdateProvider

Uses a provider class method to generate dynamic UPDATE statements.

/**
 * Specifies provider class/method for dynamic UPDATE statements
 */
@interface UpdateProvider {
    /** Provider class containing the SQL generation method */
    Class<?> type();
    
    /** Method name in the provider class */
    String method();
}

@DeleteProvider

Uses a provider class method to generate dynamic DELETE statements.

/**
 * Specifies provider class/method for dynamic DELETE statements
 */
@interface DeleteProvider {
    /** Provider class containing the SQL generation method */
    Class<?> type();
    
    /** Method name in the provider class */
    String method();
}

Result Mapping Annotations

@Results

Container annotation for defining result mappings between database columns and Java object properties.

/**
 * Container for result mappings
 */
@interface Results {
    /** Optional result map ID for reuse */
    String id() default "";
    
    /** Array of individual result mappings */
    Result[] value();
}

@Result

Maps individual database columns to Java object properties.

/**
 * Maps column to property with optional type handling
 */
@interface Result {
    /** Whether this column represents an ID/primary key */
    boolean id() default false;
    
    /** Database column name */
    String column() default "";
    
    /** Java property name */
    String property() default "";
    
    /** Java type for the property */
    Class<?> javaType() default void.class;
    
    /** JDBC type for the column */
    JdbcType jdbcType() default JdbcType.UNDEFINED;
    
    /** Custom type handler for conversion */
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
    
    /** One-to-one association mapping */
    One one() default @One;
    
    /** One-to-many association mapping */
    Many many() default @Many;
}

Usage Examples:

public interface UserMapper {
    @Select("SELECT id, user_name, email_addr, created_at FROM users WHERE id = #{id}")
    @Results({
        @Result(column = "id", property = "id", id = true),
        @Result(column = "user_name", property = "name"),
        @Result(column = "email_addr", property = "email"),
        @Result(column = "created_at", property = "createdAt", javaType = LocalDateTime.class)
    })
    User findById(@Param("id") Long id);
    
    // Reusable result map
    @Select("SELECT id, user_name, email_addr FROM users")
    @Results(id = "userResultMap", value = {
        @Result(column = "id", property = "id", id = true),
        @Result(column = "user_name", property = "name"),
        @Result(column = "email_addr", property = "email")
    })
    List<User> findAll();
    
    // Reference existing result map
    @Select("SELECT id, user_name, email_addr FROM users WHERE status = #{status}")
    @ResultMap("userResultMap")
    List<User> findByStatus(@Param("status") String status);
}

Association Annotations

@One

Defines one-to-one associations with nested object loading.

/**
 * One-to-one association mapping
 */
@interface One {
    /** SELECT statement for loading the associated object */
    String select() default "";
    
    /** Fetch type - LAZY or EAGER */
    FetchType fetchType() default FetchType.DEFAULT;
    
    /** Result map for the association */
    String resultMap() default "";
}

@Many

Defines one-to-many associations with collection loading.

/**
 * One-to-many association mapping
 */
@interface Many {
    /** SELECT statement for loading the associated collection */
    String select() default "";
    
    /** Fetch type - LAZY or EAGER */
    FetchType fetchType() default FetchType.DEFAULT;
    
    /** Result map for the association */
    String resultMap() default "";
}

Usage Examples:

public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    @Results({
        @Result(column = "id", property = "id", id = true),
        @Result(column = "name", property = "name"),
        @Result(column = "profile_id", property = "profile", 
                one = @One(select = "findProfileById", fetchType = FetchType.LAZY)),
        @Result(column = "id", property = "orders",
                many = @Many(select = "findOrdersByUserId", fetchType = FetchType.LAZY))
    })
    User findUserWithAssociations(@Param("id") Long id);
    
    @Select("SELECT * FROM profiles WHERE id = #{id}")
    Profile findProfileById(@Param("id") Long id);
    
    @Select("SELECT * FROM orders WHERE user_id = #{userId}")
    List<Order> findOrdersByUserId(@Param("userId") Long userId);
}

Configuration Annotations

@Options

Configures various statement execution options.

/**
 * Specifies various statement options
 */
@interface Options {
    /** Use cache for this statement */
    boolean useCache() default true;
    
    /** Flush cache before executing this statement */
    boolean flushCache() default false;
    
    /** Result set type */
    ResultSetType resultSetType() default ResultSetType.DEFAULT;
    
    /** Statement type */
    StatementType statementType() default StatementType.PREPARED;
    
    /** Fetch size hint for the driver */
    int fetchSize() default -1;
    
    /** Query timeout in seconds */
    int timeout() default -1;
    
    /** Use generated keys for insert statements */
    boolean useGeneratedKeys() default false;
    
    /** Property to store generated key value */
    String keyProperty() default "";
    
    /** Column name of the generated key */
    String keyColumn() default "";
    
    /** Result set names for procedures with multiple result sets */
    String resultSets() default "";
}

Usage Examples:

public interface UserMapper {
    @Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int insert(User user);
    
    @Select("SELECT * FROM users")
    @Options(fetchSize = 100, timeout = 30, useCache = false)
    List<User> findAllWithOptions();
    
    @Update("UPDATE users SET status = 'INACTIVE'")
    @Options(flushCache = true)
    int deactivateAllUsers();
}

@Param

Specifies parameter names for SQL statements when method parameters don't match placeholders.

/**
 * Specifies parameter name for SQL statements
 */
@interface Param {
    /** Parameter name to use in SQL */
    String value();
}

Usage Examples:

public interface UserMapper {
    @Select("SELECT * FROM users WHERE name = #{userName} AND status = #{userStatus}")
    List<User> findByNameAndStatus(@Param("userName") String name, 
                                   @Param("userStatus") String status);
    
    @Update("UPDATE users SET email = #{newEmail} WHERE id = #{userId}")
    int updateEmail(@Param("userId") Long id, @Param("newEmail") String email);
}

@SelectKey

Configures key generation for insert operations.

/**
 * Specifies key generation strategy
 */
@interface SelectKey {
    /** SQL statement(s) for key generation */
    String[] statement();
    
    /** Property to store the generated key */
    String keyProperty();
    
    /** Column name of the generated key */
    String keyColumn() default "";
    
    /** Execute before the main statement (true) or after (false) */
    boolean before();
    
    /** Result type of the key */
    Class<?> resultType();
    
    /** Statement type for key generation */
    StatementType statementType() default StatementType.PREPARED;
}

Usage Examples:

public interface UserMapper {
    // MySQL auto-increment key
    @Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", 
               keyProperty = "id", 
               before = false, 
               resultType = Long.class)
    int insertUser(User user);
    
    // Oracle sequence key
    @Insert("INSERT INTO users (id, name, email) VALUES (#{id}, #{name}, #{email})")
    @SelectKey(statement = "SELECT user_seq.nextval FROM dual", 
               keyProperty = "id", 
               before = true, 
               resultType = Long.class)
    int insertUserOracle(User user);
}

Cache Configuration Annotations

@CacheNamespace

Configures caching behavior for the entire mapper interface.

/**
 * Specifies cache configuration for mapper
 */
@interface CacheNamespace {
    /** Cache implementation class */
    Class<? extends Cache> implementation() default PerpetualCache.class;
    
    /** Eviction policy classes */
    Class<? extends Cache> eviction() default LruCache.class;
    
    /** Flush interval in milliseconds */
    long flushInterval() default 0;
    
    /** Maximum cache size */
    int size() default 1024;
    
    /** Read/write cache (true) or read-only cache (false) */
    boolean readWrite() default true;
    
    /** Use blocking cache to prevent cache stampede */
    boolean blocking() default false;
    
    /** Additional cache properties */
    Property[] properties() default {};
}

@interface Property {
    String name();
    String value();
}

@CacheNamespaceRef

References cache configuration from another mapper.

/**
 * References cache configuration from another mapper
 */
@interface CacheNamespaceRef {
    /** Referenced mapper class */
    Class<?> value() default void.class;
    
    /** Referenced namespace name */
    String name() default "";
}

Usage Examples:

@CacheNamespace(
    implementation = PerpetualCache.class,
    eviction = LruCache.class,
    flushInterval = 60000,
    size = 512,
    readWrite = true,
    blocking = true
)
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    @Options(useCache = true)
    User findById(@Param("id") Long id);
}

// Reference cache from another mapper
@CacheNamespaceRef(UserMapper.class)
public interface UserProfileMapper {
    @Select("SELECT * FROM user_profiles WHERE user_id = #{userId}")
    UserProfile findByUserId(@Param("userId") Long userId);
}

Utility Annotations

@Mapper

Marks an interface as a MyBatis mapper for component scanning.

/**
 * Marks interface as MyBatis mapper
 */
@interface Mapper {
}

@Flush

Marks a method to flush batch statements.

/**
 * Marks method to flush batch statements
 */
@interface Flush {
}

@Lang

Specifies a custom language driver for dynamic SQL processing.

/**
 * Specifies language driver for dynamic SQL
 */
@interface Lang {
    /** Language driver class */
    Class<? extends LanguageDriver> value();
}

Usage Examples:

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User findById(@Param("id") Long id);
    
    @Flush
    List<BatchResult> flush();
    
    @Lang(XMLLanguageDriver.class)
    @Select("SELECT * FROM users WHERE <if test='name != null'>name = #{name}</if>")
    List<User> findByCondition(@Param("name") String name);
}

Types

/**
 * Fetch types for associations
 */
enum FetchType {
    /** Use global lazy loading setting */
    DEFAULT,
    
    /** Load association eagerly */
    EAGER,
    
    /** Load association lazily */
    LAZY
}

/**
 * Result set types
 */
enum ResultSetType {
    /** Use driver default */
    DEFAULT,
    
    /** Forward-only result set */
    FORWARD_ONLY,
    
    /** Scroll-insensitive result set */
    SCROLL_INSENSITIVE,
    
    /** Scroll-sensitive result set */
    SCROLL_SENSITIVE
}

/**
 * Statement types
 */
enum StatementType {
    /** Regular statement */
    STATEMENT,
    
    /** Prepared statement (default) */
    PREPARED,
    
    /** Callable statement for stored procedures */
    CALLABLE
}

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