5.5 KiB
5.5 KiB
UTS Supabase Count API 使用示例
新增的 Count API
基于对 Supabase 官方 SDK count 操作符的分析,我们在 aksupa.uts 中添加了更符合官方习惯的 count API。
新增的方法
1. count() 方法
count(option: CountOption = 'exact'): AkSupaQueryBuilder
- 参数:
'exact' | 'planned' | 'estimated' - 默认:
'exact' - 效果:自动启用
head: true模式,只返回 count 不返回数据
2. 便捷方法
countExact(): AkSupaQueryBuilder // 等同于 count('exact')
countEstimated(): AkSupaQueryBuilder // 等同于 count('estimated')
countPlanned(): AkSupaQueryBuilder // 等同于 count('planned')
3. head() 方法
head(enable: boolean = true): AkSupaQueryBuilder
- 效果:启用 head 模式,只返回元数据,不返回实际数据
使用示例对比
旧用法(仍然支持)
// 只获取 count
const result = await supa
.from('assignments')
.select('', { count: 'exact', head: true })
.eq('teacher_id', userId)
.execute();
const total = result.total;
// 获取数据和 count
const result = await supa
.from('assignments')
.select('*', { count: 'exact' })
.eq('teacher_id', userId)
.execute();
新用法(推荐)
// 只获取 count - 更简洁
const result = await supa
.from('assignments')
.eq('teacher_id', userId)
.countExact()
.execute();
const total = result.count; // 注意:使用 count 属性
// 获取数据和 count
const result = await supa
.from('assignments')
.eq('teacher_id', userId)
.select('*')
.count('exact')
.head(false) // 关闭 head 模式
.execute();
实际应用:教师仪表板更新
更新前
const assignmentStatsResponse = await supa
.from('ak_assignments')
.select('', { count: 'exact', head: true })
.eq('teacher_id', currentUser)
.execute()
const totalAssignments = assignmentStatsResponse.total
更新后
const assignmentStatsResponse = await supa
.from('ak_assignments')
.eq('teacher_id', currentUser)
.countExact()
.execute()
const totalAssignments = assignmentStatsResponse.count
性能优势
Head 模式的优势
- 减少数据传输:只返回 count 和元数据,不返回实际行数据
- 降低内存使用:客户端无需处理大量数据
- 提升响应速度:网络传输量大幅减少
自动优化
countExact()等方法自动启用head: true- 自动设置正确的 Prefer header
- 自动处理响应解析
API 设计对比
Supabase JavaScript SDK
const { count } = await supabase
.from('table')
.select('*', { count: 'exact', head: true })
Supabase Swift SDK
let count = try await supabase
.from("table")
.select("*", count: .exact)
.execute(head: true)
.count
我们的 UTS API
const { count } = await supa
.from('table')
.countExact()
.execute()
兼容性
向后兼容
- 旧的
getcount参数仍然支持 - 旧的
select('', { count: 'exact', head: true })语法仍然工作 - 响应格式保持一致
类型安全
export type CountOption = 'exact' | 'planned' | 'estimated';
export type AkSupaSelectOptions = {
count?: CountOption; // 新增
head?: boolean; // 新增
getcount?: string; // 保持向后兼容
// ...其他选项
};
响应格式
Head 模式响应
{
data: null, // head 模式不返回数据
count: 42, // 统计结果
total: 42, // 同 count
page: 1,
limit: 0,
hasmore: false, // head 模式不需要分页
origin: {...}, // 原始响应
status: 200,
headers: {...},
error: null
}
普通模式响应
{
data: [...], // 实际数据
count: 42, // 总数统计
total: 42, // 同 count
page: 1,
limit: 10,
hasmore: true,
origin: {...},
status: 200,
headers: {...},
error: null
}
最佳实践建议
1. 纯统计查询
// ✅ 推荐:使用 countExact()
const { count } = await supa.from('table').eq('status', 'active').countExact().execute();
// ❌ 不推荐:获取所有数据再计算长度
const { data } = await supa.from('table').eq('status', 'active').select('*').execute();
const count = data.length;
2. 数据+统计
// ✅ 推荐:一次请求获取数据和总数
const result = await supa
.from('table')
.select('*')
.count('exact')
.head(false)
.limit(10)
.execute();
// ❌ 不推荐:两次请求
const countResult = await supa.from('table').countExact().execute();
const dataResult = await supa.from('table').select('*').limit(10).execute();
3. 性能考虑
// ✅ 大表统计使用 estimated
const { count } = await supa.from('huge_table').countEstimated().execute();
// ✅ 精确统计使用 exact
const { count } = await supa.from('small_table').countExact().execute();
总结
新的 count API 提供了:
- 更简洁的语法:直接调用
countExact()而不是复杂的参数 - 更好的性能:自动启用 head 模式优化
- 更好的类型安全:CountOption 枚举
- 完全向后兼容:不破坏现有代码
- 符合官方习惯:API 设计对齐 Supabase 官方 SDK
推荐在新代码中使用新的 count API,现有代码可以逐步迁移。