Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Dynamic Query Construction Using MyBatis-Plus Wrapper Classes

Tech 1

MyBatis-Plus provides a robust abstraction layer over standard MyBatis operations through its Wrapper API, enabling programmatic SQL generation without XML configuration. The architecture centers around the Wrapper abstract class, which serves as the foundasion for all condition constructors.

Class Hierarchy

The inheritance structure follows a clear pattern:

  • Wrapper<T>: Base abstract class defining core functionality
    • AbstractWrapper<T, R, Children>: Implements SQL fragment generation for WHERE clauses
      • QueryWrapper<T>: Concrete implementation for SELECT operations using string column references
      • UpdateWrapper<T>: Concrete implementation for UPDATE operations
      • AbstractLambdaWrapper<T, Children>: Adds Lambda expression support for type-safe column referencing
        • LambdaQueryWrapper<T>: Type-safe query construction using method references
        • LambdaUpdateWrapper<T>: Type-safe update condition building

Predicate Methods

The API provides fluent methods for constructing WHERE clauses:

  • eq(column, value): Equality comparison
  • ne(column, value): Inequality comparison
  • like(column, pattern): Fuzzy matching with % wildcards
  • likeRight(column, prefix): Prefix matching (column LIKE 'prefix%')
  • gt(column, value): Greater than comparison
  • ge(column, value): Greater than or equal
  • lt(column, value): Less than comparison
  • le(column, value): Less than or equal
  • between(column, min, max): Range inclusion check
  • isNull(column): NULL value check
  • isNotNull(column): Non-NULL check
  • orderByAsc(column): Ascending sort
  • orderByDesc(column): Descending sort

Implementing QueryWrapper

For dynamic SELECT statements, QueryWrapper enables method chaining to assemble complex criteria:

public void fetchActiveUsers() {
    QueryWrapper<SysUser> criteria = new QueryWrapper<>();
    criteria.likeRight("user_name", "admin")
            .eq("status", 1)
            .isNotNull("email_address")
            .ge("login_count", 5);
    
    List<SysUser> results = userDao.selectList(criteria);
    results.forEach(System.out::println);
}

This generates SQL equivalent to:

SELECT * FROM sys_user 
WHERE user_name LIKE 'admin%' 
  AND status = 1 
  AND email_address IS NOT NULL 
  AND login_count >= 5

Sorting and Pagination

Multiple ordering rules stack sequentialy:

public List<SysUser> getOrderedRecords() {
    QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
    wrapper.orderByDesc("priority_level")
           .orderByAsc("registration_date");
    
    return userMapper.selectList(wrapper);
}

Corresponding SQL:

SELECT * FROM sys_user 
ORDER BY priority_level DESC, registration_date ASC

Batch Update Operations

UpdateWrapper facilitates conditional modifications without loading entities into memory:

public void deactivateInactiveAccounts() {
    UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
    updateWrapper.set("status", 0)
                 .set("remarks", "Auto-disabled due to inactivity")
                 .isNull("last_login_time")
                 .lt("create_time", LocalDateTime.now().minusYears(1));
    
    userMapper.update(null, updateWrapper);
}

Lambda-based Type Safety

To eliminate hardcoded column strings, LambdaQueryWrapper uses method references:

public List<SysUser> fetchByLambda() {
    LambdaQueryWrapper<SysUser> lambdaWrapper = new LambdaQueryWrapper<>();
    lambdaWrapper.select(SysUser::getId, SysUser::getUserName)
                 .like(SysUser::getEmailAddress, "@company.com")
                 .ge(SysUser::getScore, 100)
                 .orderByDesc(SysUser::getCreateTime);
    
    return userMapper.selectList(lambdaWrapper);
}

This approach provides compile-time verification of column existence while maintaining identical runtime performence to string-based wrappers.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.