# 通用查询方法
实体操作及SQL 操作分别介绍了dao查询的两种方式,在这两个查询对象中,拥有通用的方法,如分页、排序等。
# 参数设置
- 方法:
param(String name, Object value)- 设置命名参数params(Map<String, ?> params)
在SQL或过滤条件中,出现:name这样带命名的参数,需要用param系列方法设置对应的值:
dao.createQuery(Entity.class)
.where("name LIKE :name")
.param("name", "%keyword%")
.list();
# 通用参数
在SQL中使用如:name带命名的参数,可以使用框架内置的参数,方法调用时无需再传值:
CURRENT_USER_ID- 当前用户IDCURRENT_USER_NAME- 当前用户名称CURRENT_TIMESTAMP- 当前时间
// 省略了 .param("CURRENT_USER_ID", "...");
dao.createQuery(Entity.class)
.where("created_by = :CURRENT_USER_ID")
.list();
通用参数可增加自定义实现,只需实现fly.orm.dao.sql.SQLParameterCustomizer接口,并注册为bean:
@Component
public class ExampleSQLParameterCustomizer implements SQLParameterCustomizer {
@Override
public void customize(Map<String, Supplier<Object>> parameters) {
parameters.putIfAbsent("IS_CLIENT_ONLY", () -> SecurityContext.get().isClientOnly());
}
}
# 数据排序
- 方法:
orderBy(String expression)- 直接传入SQL排序表达式
# 分页查询
Spring分页默认从0开始,引入fly-data/fly-rest依赖后,改为默认从1开始。
- 方法:
offset(int offset)及limit(int limit)- 对应SQL的offset和limitpageable(Pageable pageable, boolean total)pageable(Pageable pageable)-total默认为true
Pageable详细使用说明可查看Spring Data的官方文档,示例:
- 场景:当前页为0,每页大小为10
Pageable pageable = PageRequest.of(0, 10);
QueryResult<Entity> queryResult = dao.createQuery(Entity.class)
.pageable(pageable)
.execute();
List<Entity> list = queryResult.list();
当total为true,则在分页查询时同时统计总数,可在执行后返回的QueryResult对象中获取:
long count = queryResult.total();
# 返回首记录
- 方法:
T firstOrNull()- 自动设置limit为1,返回第一条记录,不存在则返回nullT first()- 没有记录时抛出异常T singleOrNull()- 自动设置limit为2,如果结果有大于等于2条记录,则抛出异常,没有则返回nullT single()- 没有记录时抛出异常
如果需要确保条件查询返回只能有一条记录,可以选择single类型的方法。为了方便在查询后对返回结果进行处理,以上方法还支持传入Consumer。
# 返回首列记录
- 方法:
S scalarOrNull()- 自动设置limit为1,返回首行首列的值,不存在则返回nullS scalarOrNull(Class<? extends S> scalarType)- 支持指定首列的数据类型S scalar()- 没有行记录时抛出异常,有记录但该字段为空时不会抛出异常S scalar(Class<? extends S> scalarType)List<S> scalars()- 返回所有行首列的值List<S> scalars(Class<? extends S> scalarType)
如只想获得实体某条记录的name字段的值,示例:
String name = dao.createQuery(Entity.class)
.select("name")
.id("id"),
.scalar(String.class);
# 返回总数
- 方法:
long count()
最终执行的SQL为SELECT COUNT(*) FROM ... ,所以调用该方法后,查询对象中设置的查询字段无效。
withTotal()- 设置查询总数,分页时有效
# 是否存在
- 方法:
boolean exists()
自动设置limit为1,返回记录不为null时,方法返回true。
# 保留字段名格式
- 方法:
Set<String> keepResultNames(String... names)
默认查询返回时,会对字段名进行转换(转换规则),假设在默认转换的情况下,查询字段设置了别名,想要保留某些字段原格式名称,可使用该方法指定。
未设置保留字段名前:
dao.createQuery(Entity.class, Map.class)
.select("name as _name")
.first();
返回的结果:
{
"name": "..."
}
设置保留字段名后:
dao.createQuery(Entity.class, Map.class)
.select("name as _name")
.keepResultNames("_name")
.first();
返回的结果:
{
"_name": "..."
}