# dynamic-query-spring-boot-starter
**Repository Path**: ydq/dynamic-query-spring-boot-starter
## Basic Information
- **Project Name**: dynamic-query-spring-boot-starter
- **Description**: 为 spring-jdbc 提供的动态查询轻量级辅助工具,用于自动生成动态 sql,省去了手动拼接SQL的麻烦
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-08-24
- **Last Updated**: 2025-09-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# dynamic-query-spring-boot-starter
[](https://jitpack.io/#me.ydq/dynamic-query-spring-boot-starter)
为 spring-jdbc 提供的动态查询轻量级辅助工具,用于自动生成动态 sql,省去了手动拼接SQL的麻烦
---
### 品尝攻略
1. 项目下面的 `pom.xml` 中 `repositories` 标签最后面添加下面的配置
```xml
jitpack.io
https://jitpack.io
```
2. 然后再添加依赖
```xml
me.ydq
dynamic-query-spring-boot-starter
${version}
```
> [👉戳这里👈](https://jitpack.io/#me.ydq/dynamic-query-spring-boot-starter) 可以查看版本信息
---
### 食用说明
本项目除了依赖 `spring-boot-starter-jdbc` 之外,不依赖其他任何组件,当前版本仅支持 `spring-boot 3` & `java 21` 及以上版本,不支持
`spring-boot 2` 和 `java 8` ,如果有需要可以自行修改部分语法以兼容低版本的 `spring-boot` 和 `java`
(应该仅仅只是一些语法层面的兼容和调整,理论上很容易移植)
另外当前版本理论上支持 `spring-boot 3` 甚至可能是 `spring-boot 4` 的多个版本,为了避免依赖冲突,没有做强依赖传递
底层实际上是直接利用了 `NamedParameterJdbcTemplate` 来进行查询,当 Spring ApplicationContext 中存在
`NamedParameterJdbcTemplate` 时,本 starter 会自动初始化 `DynamicQuery`,你可以直接注入使用,当然你也可以手动初始化
默认配置:
- 数据库方言:默认只提供 MySQL 方言,字段、表名使用【`】进行包裹,翻页直接在SQL后面追加 LIMIT offset,size
- 表名转换器:默认直接根据类名转为下划线风格
- 列名转换器:默认直接根据字段名称转为下划线风格
- RowMapperProvider:默认直接使用 Spring 提供的 BeanPropertyRowMapper 根据当前类返回对应的 RowMapper(spring-boot
默认也是下划线风格)
> 你也可以自己手动注册 DynamicQuery 或者 直接往 Spring 容器中提供自定义的
> Dialect、TableConvert、ColumnConvert、RowMapperProvider 实现自动注入给
> DynamicQuery
```java
//下面是默认示例,不需要自己注入不做任何配置 当 Spring 容器中存在 NamedParameterJdbcTemplate 时会自动注册 DynamicQuery 对象
// 也可自己手动注册一个 DynamicQueyr 的 Bean
public DynamicQuery dynamicQuery(NamedParameterJdbcTemplate namedParameterJdbcTemplate,
@Autowired(required = false) Dialect dialect,
@Autowired(required = false) TableConvert tableConvert,
@Autowired(required = false) ColumnConvert columnConvert,
@Autowired(required = false) RowMapperProvider rowMapperProvider) {
return DynamicQuery.of(namedParameterJdbcTemplate, dialect, tableConvert, columnConvert, rowMapperProvider);
}
//下面是一个表名转换器的参考,比如表名会从 @Table 注解中读取,这个 Bean 会自动注入给 默认的 DynamicQuery
@Bean
public TableConvert tableConvert() {
return cls -> {
Table table = cls.getAnnotation(Table.class);
String tableName = table.value();
if (tableName.isEmpty()) {
tableName = table.name();
}
return tableName;
};
}
```
---
### 烹饪姿势
#### 多条件的列表查询
```java
import me.ydq.DynamicQuery;
@Autowired
DynamicQuery query;
public void demo(){
// query.table() 有多个重载,支持传入 表名 或 表名转换器,参数优先级高于 DynamicQuery 中的配置
List list = query.table(User.class)
.where(u -> u
.eq(User::getStatus, 1)
.or(
o -> o.eq(User::getGender, 1).ge(User::getAge, 18), //链式调用的一组条件为 and
o -> o.eq(User::getGender, 0).ge(User::getAge, 16) //每组条件(独立的表达式)之间为 or
)
.contains(User::getMobile, "8888")
)
.asc(User::getId)
.order("field(status,5,2,1,4,3) DESC")
.list();
}
```
生成的SQL如下:
```sql
SELECT * FROM `user`
WHERE
`status` = :status_1
AND
(
( `gender` = :gender_2 AND `age` >= :age_3 )
OR
( `gender` = :gender_4 AND `age` >= :age_5 )
)
AND `mobile` LIKE :mobile_6
ORDER BY
`id` ASC ,
field(status,5,2,1,4,3) DESC
```
---
#### page 查询
```java
//支持 page 查询,自动生成 count 查询语句进行一次 count 查询
PageData page = query.table(User.class, "my_user_table")
.where(u -> u
//所有的 eq/like/in 等查询方法 第一个参数支持传入动态条件判断,返回 false 时 本条件不生效
.between(() -> true, User::getAge, 18, 25)
)
//支持传入自定义的字段 别名等信息,最后传入一个 RowMapper 可以返回指定的类型
.page("DISTINCT `nickname` AS xx", 50, 10, (rs, i) -> rs.getString("xx"));
List list = page.getList();//列表查询
Integer count = page.getTotal();//count 查询
```
生成的SQL如下:
```sql
SELECT DISTINCT `nickname` AS nickname
FROM `my_user_table`
WHERE `age` BETWEEN :age_1 AND :age_2
LIMIT 50 , 10
```
更多使用方法请参考[👉测试用例👈](src/test/java/me/ydq/QueryTest.java)