MyBatis-Plus Extension module providing advanced features including service layers, Kotlin extensions, SQL parsers, caching mechanisms, and various interceptors for enhanced ORM functionality
npx @tessl/cli install tessl/maven-com-baomidou--mybatis-plus-extension@3.5.0MyBatis-Plus Extension is an advanced toolkit that enhances MyBatis-Plus with comprehensive service layers, Kotlin extensions, SQL parsers, caching mechanisms, and various interceptors. It provides higher-level abstractions and utilities that build upon the core MyBatis-Plus functionality to significantly reduce boilerplate code and improve development productivity in enterprise Java applications.
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.7</version>
</dependency>Or Gradle:
implementation 'com.baomidou:mybatis-plus-extension:3.5.7'import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.conditions.query.QueryWrapper;
// Define a service interface
public interface UserService extends IService<User> {
// Custom methods can be added here
}
// Implement the service
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// ServiceImpl provides all CRUD operations automatically
}
// Use the service
@Autowired
private UserService userService;
// Basic CRUD operations
User user = new User("John", "john@example.com");
userService.save(user);
List<User> users = userService.list();
User foundUser = userService.getById(1L);
// Query with conditions
List<User> activeUsers = userService.list(
new QueryWrapper<User>().eq("active", true)
);
// Pagination
Page<User> page = userService.page(new Page<>(1, 10));MyBatis-Plus Extension is built around several key architectural components:
IService interface and ServiceImpl base class providing comprehensive CRUD operationsDb class providing service-layer operations without dependency injectionComprehensive service layer with IService interface providing all common CRUD operations, batch processing, and method chaining. The ServiceImpl base class offers ready-to-use implementations.
public interface IService<T> {
int DEFAULT_BATCH_SIZE = 1000;
// Save operations
boolean save(T entity);
boolean saveBatch(Collection<T> entityList);
boolean saveBatch(Collection<T> entityList, int batchSize);
boolean saveOrUpdate(T entity);
boolean saveOrUpdateBatch(Collection<T> entityList);
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
// Query operations
T getById(Serializable id);
Optional<T> getOptById(Serializable id);
List<T> list();
List<T> list(Wrapper<T> queryWrapper);
List<T> listByIds(Collection<? extends Serializable> idList);
List<T> listByMap(Map<String, Object> columnMap);
T getOne(Wrapper<T> queryWrapper);
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
Optional<T> getOneOpt(Wrapper<T> queryWrapper);
Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx);
Map<String, Object> getMap(Wrapper<T> queryWrapper);
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
Page<T> page(IPage<T> page);
<E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper);
long count();
long count(Wrapper<T> queryWrapper);
boolean exists(Wrapper<T> queryWrapper);
// Update operations
boolean updateById(T entity);
boolean update(T entity, Wrapper<T> updateWrapper);
boolean update(Wrapper<T> updateWrapper);
boolean updateBatchById(Collection<T> entityList);
boolean updateBatchById(Collection<T> entityList, int batchSize);
// Remove operations
boolean removeById(Serializable id);
boolean removeById(Serializable id, boolean useFill);
boolean removeById(T entity);
boolean removeByIds(Collection<?> list);
boolean removeByIds(Collection<?> list, boolean useFill);
boolean removeByMap(Map<String, Object> columnMap);
boolean remove(Wrapper<T> queryWrapper);
boolean removeBatchByIds(Collection<?> list);
boolean removeBatchByIds(Collection<?> list, boolean useFill);
// Chain operations
QueryChainWrapper<T> query();
LambdaQueryChainWrapper<T> lambdaQuery();
LambdaQueryChainWrapper<T> lambdaQuery(T entity);
KtQueryChainWrapper<T> ktQuery();
UpdateChainWrapper<T> update();
LambdaUpdateChainWrapper<T> lambdaUpdate();
KtUpdateChainWrapper<T> ktUpdate();
// Utility methods
BaseMapper<T> getBaseMapper();
Class<T> getEntityClass();
}
public abstract class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Autowired
protected M baseMapper;
protected final Log log;
private Class<T> entityClass;
private Class<M> mapperClass;
private volatile SqlSessionFactory sqlSessionFactory;
public M getBaseMapper();
public Class<T> getEntityClass();
public Class<M> getMapperClass();
protected SqlSessionFactory getSqlSessionFactory();
}Fluent API for building complex database queries and updates with method chaining. Supports both traditional and lambda-based property references.
public class QueryChainWrapper<T> implements ChainQuery<T> {
public QueryChainWrapper(BaseMapper<T> baseMapper);
public QueryChainWrapper(Class<T> entityClass);
public List<T> list();
public T one();
public long count();
public Page<T> page(IPage<T> page);
}
public class UpdateChainWrapper<T> implements ChainUpdate<T> {
public UpdateChainWrapper(BaseMapper<T> baseMapper);
public UpdateChainWrapper(Class<T> entityClass);
public boolean update();
public boolean remove();
}Interceptor-based plugin architecture supporting pagination, multi-tenancy, data permissions, optimistic locking, and SQL security features.
public class MybatisPlusInterceptor implements Interceptor {
public void addInnerInterceptor(InnerInterceptor innerInterceptor);
public List<InnerInterceptor> getInterceptors();
}
public interface InnerInterceptor {
void willDoQuery(Executor executor, MappedStatement ms, Object parameter,
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql);
void beforeQuery(Executor executor, MappedStatement ms, Object parameter,
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql);
}Advanced pagination support with automatic total count queries and database-specific SQL dialect handling for optimal performance across different database systems.
public class Page<T> implements IPage<T> {
// Constructors
public Page();
public Page(long current, long size);
public Page(long current, long size, long total);
public Page(long current, long size, boolean searchCount);
public Page(long current, long size, long total, boolean searchCount);
// Core getters
public List<T> getRecords();
public long getTotal();
public long getSize();
public long getCurrent();
public long getPages();
public List<OrderItem> orders();
// Fluent setters
public Page<T> setRecords(List<T> records);
public Page<T> setTotal(long total);
public Page<T> setSize(long size);
public Page<T> setCurrent(long current);
public Page<T> addOrder(OrderItem... items);
public Page<T> addOrder(List<OrderItem> items);
// Pagination utilities
public boolean hasPrevious();
public boolean hasNext();
public boolean searchCount();
public boolean optimizeCountSql();
public Page<T> setSearchCount(boolean searchCount);
public Page<T> setOptimizeCountSql(boolean optimizeCountSql);
// Static factory methods
public static <T> Page<T> of(long current, long size);
public static <T> Page<T> of(long current, long size, long total);
public static <T> Page<T> of(long current, long size, boolean searchCount);
public static <T> Page<T> of(long current, long size, long total, boolean searchCount);
}Base Model class enabling entity objects to perform their own database operations, following the Active Record pattern for simplified data access.
public abstract class Model<T extends Model<?>> implements Serializable {
public boolean insert();
public boolean deleteById();
public boolean updateById();
public T selectById();
public List<T> selectAll();
public Page<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper);
}Db utility class providing static methods for direct database operations without requiring service layer dependency injection, ideal for utility classes and static contexts.
public class Db {
// Save operations
public static <T> boolean save(T entity);
public static <T> boolean saveBatch(Collection<T> entityList);
public static <T> boolean saveBatch(Collection<T> entityList, int batchSize);
public static <T> boolean saveOrUpdate(T entity);
public static <T> boolean saveOrUpdateBatch(Collection<T> entityList);
public static <T> boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
// Query operations
public static <T> T getById(Serializable id, Class<T> entityClass);
public static <T> List<T> list(Class<T> entityClass);
public static <T> List<T> list(Class<T> entityClass, Wrapper<T> queryWrapper);
public static <T> List<T> listByIds(Collection<? extends Serializable> idList, Class<T> entityClass);
public static <T> List<T> listByMap(Map<String, Object> columnMap, Class<T> entityClass);
public static <T> T getOne(Class<T> entityClass, Wrapper<T> queryWrapper);
public static <T> Map<String, Object> getMap(Class<T> entityClass, Wrapper<T> queryWrapper);
public static <T> <V> V getObj(Class<T> entityClass, Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
public static <T> long count(Class<T> entityClass);
public static <T> long count(Class<T> entityClass, Wrapper<T> queryWrapper);
public static <T> boolean exists(Class<T> entityClass, Wrapper<T> queryWrapper);
// Update operations
public static <T> boolean updateById(T entity);
public static <T> boolean update(T entity, Wrapper<T> updateWrapper);
public static <T> boolean update(Class<T> entityClass, Wrapper<T> updateWrapper);
public static <T> boolean updateBatchById(Collection<T> entityList);
public static <T> boolean updateBatchById(Collection<T> entityList, int batchSize);
// Remove operations
public static <T> boolean removeById(Serializable id, Class<T> entityClass);
public static <T> boolean removeByIds(Collection<? extends Serializable> idList, Class<T> entityClass);
public static <T> boolean removeByMap(Map<String, Object> columnMap, Class<T> entityClass);
public static <T> boolean remove(Class<T> entityClass, Wrapper<T> queryWrapper);
// Pagination operations
public static <T, E extends IPage<T>> E page(E page, Class<T> entityClass);
public static <T, E extends IPage<T>> E page(E page, Class<T> entityClass, Wrapper<T> queryWrapper);
public static <E extends IPage<Map<String, Object>>> E pageMaps(E page, Class<?> entityClass, Wrapper<?> queryWrapper);
// Chain operations
public static <T> QueryChainWrapper<T> query(Class<T> entityClass);
public static <T> LambdaQueryChainWrapper<T> lambdaQuery(Class<T> entityClass);
public static <T> KtQueryChainWrapper<T> ktQuery(Class<T> entityClass);
public static <T> UpdateChainWrapper<T> update(Class<T> entityClass);
public static <T> LambdaUpdateChainWrapper<T> lambdaUpdate(Class<T> entityClass);
public static <T> KtUpdateChainWrapper<T> ktUpdate(Class<T> entityClass);
}Type-safe Kotlin DSL providing enhanced developer experience with property-based query building and Kotlin-specific language features.
class KtQueryWrapper<T>(entity: T? = null) : AbstractKtWrapper<T, KtQueryWrapper<T>>() {
fun select(vararg columns: KProperty<*>): KtQueryWrapper<T>
fun getSqlSelect(): String
}
class KtUpdateWrapper<T>(entity: T? = null) : AbstractKtWrapper<T, KtUpdateWrapper<T>>()// Base service interface providing CRUD operations
public interface IService<T> {
int DEFAULT_BATCH_SIZE = 1000;
}
// Base service implementation
public abstract class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Autowired
protected M baseMapper;
protected final Log log;
private Class<T> entityClass;
private Class<M> mapperClass;
private volatile SqlSessionFactory sqlSessionFactory;
}
// Pagination container
public class Page<T> implements IPage<T> {
protected List<T> records;
protected long total;
protected long size;
protected long current;
protected List<OrderItem> orders;
protected boolean optimizeCountSql = true;
protected boolean searchCount = true;
protected boolean optimizeJoinOfCountSql = true;
protected Long maxLimit;
protected String countId;
}
// Active Record base class
public abstract class Model<T extends Model<?>> implements Serializable {
protected Serializable pkVal();
}
// Main interceptor coordinator
public class MybatisPlusInterceptor implements Interceptor {
private List<InnerInterceptor> interceptors;
}