MyBatis-Plus is an enhanced toolkit for MyBatis providing CRUD operations, query wrappers, pagination, code generation, and Spring Boot integration.
npx @tessl/cli install tessl/maven-com-baomidou--mybatis-plus@3.5.0MyBatis-Plus is a powerful enhancement toolkit for MyBatis that dramatically simplifies Java database development. It provides out-of-the-box features including automatic CRUD operations, flexible query wrappers with lambda-style API support, code generation, pagination, optimistic locking, and comprehensive Spring Boot integration while maintaining full backward compatibility with standard MyBatis.
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>// Core mapper and service imports
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
// Query wrapper imports
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
// Annotation imports
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.IdType;
// Pagination imports
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;// Entity definition with annotations
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
@TableField("user_name")
private String name;
private Integer age;
private String email;
// getters and setters...
}
// Mapper interface extending BaseMapper
public interface UserMapper extends BaseMapper<User> {
// Custom methods can be added here
}
// Service interface and implementation
public interface UserService extends IService<User> {
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
// Usage examples
@Autowired
private UserService userService;
// Basic CRUD operations
User user = new User();
user.setName("John");
user.setAge(25);
user.setEmail("john@example.com");
// Save user
userService.save(user);
// Query with wrapper
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 25).like("name", "John");
List<User> users = userService.list(wrapper);
// Lambda query
List<User> adults = userService.lambdaQuery()
.ge(User::getAge, 18)
.list();
// Pagination
Page<User> page = new Page<>(1, 10);
IPage<User> userPage = userService.page(page, wrapper);MyBatis-Plus is organized into several key components:
BaseMapper interface providing comprehensive database operations with automatic SQL generation for standard CRUD operations.
public interface BaseMapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int updateById(T entity);
T selectById(Serializable id);
List<T> selectList(Wrapper<T> queryWrapper);
Long selectCount(Wrapper<T> queryWrapper);
// ... additional methods
}Flexible query wrapper system supporting both string-based and lambda-style conditions for building complex SQL queries.
public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>> {
public QueryWrapper<T> eq(String column, Object val);
public QueryWrapper<T> ne(String column, Object val);
public QueryWrapper<T> gt(String column, Object val);
public QueryWrapper<T> like(String column, Object val);
// ... additional condition methods
}
public class LambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, LambdaQueryWrapper<T>> {
public LambdaQueryWrapper<T> eq(SFunction<T, ?> fn, Object val);
public LambdaQueryWrapper<T> ne(SFunction<T, ?> fn, Object val);
public LambdaQueryWrapper<T> gt(SFunction<T, ?> fn, Object val);
// ... additional lambda condition methods
}High-level service interface providing business-logic-focused methods built on top of BaseMapper functionality.
public interface IService<T> {
boolean save(T entity);
boolean saveBatch(Collection<T> entityList);
boolean saveOrUpdate(T entity);
boolean removeById(Serializable id);
boolean updateById(T entity);
T getById(Serializable id);
List<T> list();
List<T> list(Wrapper<T> queryWrapper);
<E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper);
long count(Wrapper<T> queryWrapper);
// ... additional service methods
}Comprehensive annotation system for mapping Java entities to database tables with support for custom naming, field strategies, and special column handling.
@Target(ElementType.TYPE)
public @interface TableName {
String value() default "";
String schema() default "";
boolean keepGlobalPrefix() default false;
String resultMap() default "";
boolean autoResultMap() default false;
}
@Target(ElementType.FIELD)
public @interface TableId {
String value() default "";
IdType type() default IdType.NONE;
}
@Target(ElementType.FIELD)
public @interface TableField {
String value() default "";
boolean exist() default true;
String condition() default "";
String update() default "";
FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;
FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;
FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;
FieldFill fill() default FieldFill.DEFAULT;
boolean select() default true;
boolean keepGlobalFormat() default false;
JdbcType jdbcType() default JdbcType.UNDEFINED;
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
String numericScale() default "";
}Automated code generation system for creating entity classes, mapper interfaces, service classes, and controller classes from database schemas.
public class AutoGenerator {
public void execute();
public AutoGenerator setGlobalConfig(GlobalConfig globalConfig);
public AutoGenerator setDataSourceConfig(DataSourceConfig dataSourceConfig);
public AutoGenerator setPackageConfig(PackageConfig packageConfig);
public AutoGenerator setStrategyConfig(StrategyConfig strategyConfig);
public AutoGenerator setTemplateConfig(TemplateConfig templateConfig);
}
public class GlobalConfig {
public GlobalConfig setOutputDir(String outputDir);
public GlobalConfig setFileOverride(boolean fileOverride);
public GlobalConfig setAuthor(String author);
public GlobalConfig setEnableKotlin(boolean enableKotlin);
public GlobalConfig setSwagger(boolean swagger);
public GlobalConfig setDateType(DateType dateType);
}Built-in pagination support with automatic count queries and flexible page configuration options.
public interface IPage<T> extends Serializable {
List<T> getRecords();
IPage<T> setRecords(List<T> records);
long getTotal();
IPage<T> setTotal(long total);
long getSize();
IPage<T> setSize(long size);
long getCurrent();
IPage<T> setCurrent(long current);
default long getPages();
default boolean hasNext();
default boolean hasPrevious();
}
public class Page<T> implements IPage<T> {
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);
}Active Record pattern support allowing entities to perform database operations directly without requiring separate mapper or service classes.
public abstract class Model<T extends Model<?>> implements Serializable, Cloneable {
public boolean insert();
public boolean insertOrUpdate();
public boolean updateById();
public boolean update(Wrapper<T> updateWrapper);
public boolean deleteById();
public boolean delete(Wrapper<T> queryWrapper);
public T selectById();
public T selectOne(Wrapper<T> queryWrapper);
public List<T> selectList(Wrapper<T> queryWrapper);
public <E extends IPage<T>> E selectPage(E page, Wrapper<T> queryWrapper);
public long selectCount(Wrapper<T> queryWrapper);
}Extensible plugin system for adding cross-cutting functionality like pagination, optimistic locking, tenant isolation, and SQL security.
public class MybatisPlusInterceptor implements Interceptor {
public void addInnerInterceptor(InnerInterceptor innerInterceptor);
public List<InnerInterceptor> getInterceptors();
public void setProperties(Properties properties);
}
public interface InnerInterceptor {
default boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException;
default void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException;
default boolean willDoUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException;
default void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException;
}
public class PaginationInnerInterceptor implements InnerInterceptor {
public PaginationInnerInterceptor();
public PaginationInnerInterceptor(DbType dbType);
public void setMaxLimit(Long maxLimit);
public void setOverflow(boolean overflow);
}Seamless Spring Boot integration with auto-configuration, properties binding, and starter dependencies.
@ConfigurationProperties(prefix = "mybatis-plus")
public class MybatisPlusProperties {
private String[] mapperLocations;
private String typeAliasesPackage;
private Class<?> typeAliasesSuperType;
private String typeHandlersPackage;
private ExecutorType executorType;
private Properties configurationProperties;
private GlobalConfig globalConfig;
// ... getters and setters
}
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception;
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory);
}Essential utility classes providing helper methods for common database operations, SQL execution, and metadata handling.
// SQL execution utilities
public class SqlHelper {
public static boolean retBool(Integer result);
public static boolean executeBatch(Class<?> entityClass, Log log, Collection<T> list, int batchSize, BiConsumer<SqlSession, T> consumer);
public static int executeBatch(Class<?> entityClass, Log log, Collection<T> list, int batchSize, BiPredicate<SqlSession, T> predicate);
}
// Raw SQL execution
public class SqlRunner {
public SqlRunner(DataSource dataSource);
public Map<String, Object> selectOne(String sql, Object... args);
public List<Map<String, Object>> selectList(String sql, Object... args);
public int insert(String sql, Object... args);
public int update(String sql, Object... args);
public int delete(String sql, Object... args);
}
// JDBC utilities
public class JdbcUtils {
public static DbType getDbType(String jdbcUrl);
public static String getJdbcUrl(DataSource dataSource);
public static DataSource getDataSource(String dataSourceName);
}
// Simplified querying utilities
public class SimpleQuery {
public static <T> List<T> list(LambdaQueryWrapper<T> wrapper);
public static <T> T one(LambdaQueryWrapper<T> wrapper);
public static <T> Map<String, Object> map(LambdaQueryWrapper<T> wrapper);
public static <T> Object obj(LambdaQueryWrapper<T> wrapper);
public static <T> Long count(LambdaQueryWrapper<T> wrapper);
}
// Table metadata utilities
public class TableInfoHelper {
public static TableInfo getTableInfo(Class<?> clazz);
public static void initTableInfo(MapperBuilderAssistant builderAssistant, Class<?> clazz);
public static String getTableName(Class<?> clazz);
public static List<TableFieldInfo> getFieldList(Class<?> clazz);
}// Function interface for lambda expressions
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
// Wrapper base class
public abstract class Wrapper<T> implements ISqlSegment, Serializable {
public abstract T getEntity();
public abstract String getSqlSegment();
public abstract List<Map<String, Object>> getParamNameValuePairs();
public abstract String getCustomSqlSegment();
public abstract String getExpression();
public abstract boolean isEmptyOfWhere();
public abstract boolean isEmptyOfNormal();
public abstract boolean nonEmpty();
public abstract void clear();
}
// Primary key generation strategies
public enum IdType {
AUTO(0), // Database auto-increment
NONE(1), // No primary key
INPUT(2), // User input
ASSIGN_ID(3), // Assign ID (snowflake)
ASSIGN_UUID(4); // Assign UUID
}
// Field fill strategies
public enum FieldFill {
DEFAULT, // Default, no auto-fill
INSERT, // Fill on insert
UPDATE, // Fill on update
INSERT_UPDATE; // Fill on insert and update
}
// Field strategy for conditions
public enum FieldStrategy {
IGNORED, // Ignore null and empty values
NOT_NULL, // Ignore null values only
NOT_EMPTY, // Ignore null and empty values
DEFAULT, // Use global default strategy
NEVER; // Never ignore
}
// Database types
public enum DbType {
MYSQL, MARIADB, ORACLE, DB2, H2, HSQL, SQLITE,
POSTGRE_SQL, SQL_SERVER2005, SQL_SERVER, DM,
XU_GU, KINGBASE_ES, PHOENIX, GAUSS, CLICK_HOUSE,
GBASE, GBASE_8S, OSCAR, SYBASE, OCEAN_BASE,
FIREBIRD, HIGH_GO, CUBRID, GOLDILOCKS, CSIIDB,
SAP_HANA, IMPALA, VERTICA, XCloud, REDSHIFT,
OPENGAUSS, TDENGINE, INFORMIX, SINODB, UXDB,
LEALONE, ALIYUN_ADS, PRESTO, TRINO, STARROCKS,
CLICKSTAR, POLARDBX;
}