MyBatis Dynamic SQL Plus 是一个基于 Java 原生编译期注解处理器(Annotation Processor,JSR 269)构建的轻量级增强框架。它的核心使命是:“一个注解,消除所有动态 SQL 样板代码。”
MyBatis 官方推荐的现代化数据访问工具是 MyBatis Dynamic SQL,它提供了极其优雅的、类型安全的(Type-Safe)动态 SQL 编写体验,彻底摒弃了繁琐且易错的 XML。
然而,在实际开发中,开发者必须为每一个数据库表手动编写对应的 XxxDynamicSqlSupport 类(逐一声明表名和列元数据),并手动编写带有大量 @SelectProvider 注解的 Mapper 接口。这种高度重复的样板代码使得开发体验变得冗长且难以维护。
参考 Lombok 的设计哲学,本框架将样板代码的生成前置到了代码编译期。你只需要在实体类上添加一个简单的 @DynamicMapper 注解,我们的编译器插件就会在后台默默地为你生成所需的全部底层元数据类和通用的 CRUD Mapper 接口。
- 🚀 零运行期损耗:全部通过编译期 AST 语法树解析和源码生成实现,没有运行期反射开销。
- 🛡️ 完全原生兼容:生成的代码 100% 遵循原生的 MyBatis Dynamic SQL 规范。
- ⚡ 极大提升效能:告别繁琐的复制粘贴,专注核心业务逻辑。
- 🌍 全环境适配:得益于纯正的 Java 8 编译期技术栈与非强依赖设计,本框架可以在 JDK 8、JDK 11(老牌 Spring Boot 2 环境)甚至最新的 JDK 25/26(主流的 Spring Boot 4 环境)中无缝跨版本运行。开发者无需像使用其他某些 ORM 增强框架一样为不同版本的 Spring Boot 引入不同版本的 Starter,只需一个依赖即可通吃过去与未来的所有主流环境。
由于本项目托管在 GitHub 上,你可以通过 JitPack 零配置引入。
首先,在你的 pom.xml 中添加 JitPack 仓库:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>然后引入 Starter 依赖:
<dependency>
<groupId>cn.kunter</groupId>
<artifactId>dynamic-sql-plus-spring-boot-starter</artifactId>
<version>v1.0.0</version> <!-- 替换为 GitHub 上的最新 Release Tag -->
</dependency>注意:为了让编译器能够自动发现 Annotation Processor,请确保在使用本框架的模块的
maven-compiler-plugin插件中配置了 processor 的路径。如果是多模块项目,请参考本仓库中的dynamic-sql-plus-example模块的配置。
由于本框架基于 Java 原生的编译期注解处理器生成代码,无需安装任何第三方插件。
你只需要在 IDEA 中依次打开:
Settings (Preferences) -> Build, Execution, Deployment -> Compiler -> Annotation Processors
勾选 Enable annotation processing 即可。
IDEA 会在后台自动为你生成代码,并将 target/generated-sources/annotations 标记为 Generated Sources Root,彻底告别红色波浪线!
直接在你的普通 Java Bean(Entity/Eo)上添加 @DynamicMapper 即可:
import cn.kunter.dynamic.annotations.DynamicMapper;
import cn.kunter.dynamic.annotations.TableColumn;
import cn.kunter.dynamic.annotations.TableId;
@DynamicMapper
public class UserEo {
// 标识主键,开启自动递增后生成的 insert 方法会自动配置 useGeneratedKeys
@TableId(autoIncrement = true)
private Long id;
private String username;
// 如果字段名和数据库列名不一致,可以通过 @TableColumn 自定义映射
@TableColumn(value = "user_status")
private Integer status;
// 如果该字段并非数据库字段,直接忽略即可
@TableColumn(ignore = true)
private String temporaryToken;
// 省略 getter/setter
}执行 mvn compile 或在 IDE 中进行 Build 后,去看看 target/generated-sources/annotations 目录吧!你会发现两个被自动生成的类:
UserEoDynamicSqlSupport.java:所有字段已经帮你完美映射为了SqlColumn。UserMapper.java:自带 MyBatis 通用增删改查能力的接口。
在 Service 层,你现在可以直接注入 UserMapper,不仅可以使用全套动态 SQL 语法,还可以直接享受开箱即用、完全类型安全的单表 CRUD 方法:
@Service
public class UserServiceImpl {
@Autowired
private UserMapper userMapper;
public void queryUsers() {
// 1. 根据主键查询(返回 Optional,安全防空)
Optional<UserEo> user = userMapper.selectByPrimaryKey(1L);
// 2. 根据主键更新(自动过滤掉主键本身的更新)
UserEo updateRecord = new UserEo();
updateRecord.setId(1L);
updateRecord.setStatus(0);
userMapper.updateByPrimaryKey(updateRecord);
// 3. 原生强类型动态 SQL 构建
// userMapper.select(c -> c.where(UserEoDynamicSqlSupport.status, isEqualTo(1)));
}
}tableName:默认情况下,框架会将实体类名称由驼峰转为下划线,并自动去掉结尾的Eo或Entity作为表名(例如UserEo会被推断为user)。如果你有特定的表名前缀,可以通过@DynamicMapper(tableName = "sys_user")手动指定。
autoIncrement:布尔值。如果为true,会在底层生成的insert和insertMultiple方法上自动添加@Options(useGeneratedKeys = true, keyProperty = "row.xxx"),实现主键自动回填。
value:指定确切的数据库列名。默认会将字段的驼峰命名转换为下划线(例如createTime->create_time)。ignore:如果为true,则该字段会被处理器完全忽略,不会生成对应的SqlColumn。
本项目基于开源精神构建。欢迎提交 Issue 和 Pull Request,共同建设更优雅的 Java 基础设施生态。