# 通用查询方法

实体操作SQL 操作分别介绍了dao查询的两种方式,在这两个查询对象中,拥有通用的方法,如分页、排序等。

# 参数设置

  • 方法:
  1. param(String name, Object value) - 设置命名参数
  2. params(Map<String, ?> params)

SQL或过滤条件中,出现:name这样带命名的参数,需要用param系列方法设置对应的值:

dao.createQuery(Entity.class)
    .where("name LIKE :name")
    .param("name", "%keyword%")
    .list();

# 通用参数

SQL中使用如:name带命名的参数,可以使用框架内置的参数,方法调用时无需再传值:

  1. CURRENT_USER_ID - 当前用户ID
  2. CURRENT_USER_NAME - 当前用户名称
  3. 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开始。

  • 方法:
  1. offset(int offset)limit(int limit) - 对应SQLoffsetlimit
  2. pageable(Pageable pageable, boolean total)
  3. 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();

totaltrue,则在分页查询时同时统计总数,可在执行后返回的QueryResult对象中获取:

long count = queryResult.total();

# 返回首记录

  • 方法:
  1. T firstOrNull() - 自动设置limit为1,返回第一条记录,不存在则返回null
  2. T first() - 没有记录时抛出异常
  3. T singleOrNull() - 自动设置limit为2,如果结果有大于等于2条记录,则抛出异常,没有则返回null
  4. T single() - 没有记录时抛出异常

如果需要确保条件查询返回只能有一条记录,可以选择single类型的方法。为了方便在查询后对返回结果进行处理,以上方法还支持传入Consumer

# 返回首列记录

  • 方法:
  1. S scalarOrNull() - 自动设置limit为1,返回首行首列的值,不存在则返回null
  2. S scalarOrNull(Class<? extends S> scalarType) - 支持指定首列的数据类型
  3. S scalar() - 没有行记录时抛出异常,有记录但该字段为空时不会抛出异常
  4. S scalar(Class<? extends S> scalarType)
  5. List<S> scalars() - 返回所有行首列的值
  6. List<S> scalars(Class<? extends S> scalarType)

如只想获得实体某条记录的name字段的值,示例:

String name = dao.createQuery(Entity.class)
    .select("name")
    .id("id"),
	.scalar(String.class);

# 返回总数

  • 方法:
  1. long count()

最终执行的SQLSELECT COUNT(*) FROM ... ,所以调用该方法后,查询对象中设置的查询字段无效。

  1. 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": "..."
}
顶部