5.3 KiB
5.3 KiB
直接使用 AkSupa 链式调用指南
优势: 无需 API 包装层,直接使用 supaClient 链式调用,代码更简洁高效!
基本用法
1. 导入 supaClient
import supaClient from '@/components/supadb/aksupainstance.uts'
2. 基本 CRUD 操作
查询数据
// 获取所有项目
const result = await supaClient
.from('ak_training_projects')
.select('*')
.execute()
// 带条件查询
const result = await supaClient
.from('ak_assignments')
.select('*, ak_training_projects(*)')
.eq('student_id', studentId)
.eq('status', 'pending')
.order('created_at', { ascending: false })
.limit(20)
.execute()
// 单条记录查询
const result = await supaClient
.from('ak_training_projects')
.select('*')
.eq('id', projectId)
.single()
.execute()
插入数据
// 创建新记录
const result = await supaClient
.from('ak_training_records')
.insert({
title: '晨跑训练',
duration: 30,
calories: 200,
student_id: 'user123',
created_at: new Date().toISOString()
})
.single()
.execute()
更新数据
// 更新记录
const result = await supaClient
.from('ak_assignments')
.update({
status: 'completed',
completed_at: new Date().toISOString(),
score: 95
})
.eq('id', assignmentId)
.single()
.execute()
删除数据
// 删除记录
const result = await supaClient
.from('ak_training_records')
.delete()
.eq('id', recordId)
.execute()
3. 高级查询
复杂筛选
// 多条件筛选
const result = await supaClient
.from('ak_training_projects')
.select('*')
.eq('category', '体能训练')
.gte('difficulty', 3)
.lte('difficulty', 5)
.eq('is_active', true)
.ilike('name', '%跑步%')
.execute()
分页查询
// 分页获取数据
const result = await supaClient
.from('ak_assignments')
.select('*')
.range(0, 19) // 获取前20条
.order('created_at', { ascending: false })
.execute()
聚合查询
// 统计查询
const result = await supaClient
.from('ak_training_records')
.select('*', { count: 'exact' })
.eq('student_id', studentId)
.execute()
// result.count 包含总数
4. 实时订阅
export default {
data() {
return {
subscription: null
}
},
onLoad() {
this.setupRealtimeSubscription()
},
onUnload() {
if (this.subscription) {
this.subscription.unsubscribe()
}
},
methods: {
setupRealtimeSubscription() {
this.subscription = supaClient
.from('ak_assignments')
.on('INSERT', (payload) => {
console.log('新作业:', payload.new)
// 更新本地数据
this.assignments.push(payload.new)
})
.on('UPDATE', (payload) => {
console.log('作业更新:', payload.new)
// 更新本地数据
this.updateLocalAssignment(payload.new)
})
.on('DELETE', (payload) => {
console.log('作业删除:', payload.old)
// 从本地数据中移除
this.removeLocalAssignment(payload.old.id)
})
.subscribe()
}
}
}
5. 文件上传
// 上传文件到 Supabase Storage
const result = await supaClient
.storage
.from('training-files')
.upload(`${Date.now()}_${fileName}`, filePath)
.execute()
if (result.success) {
const fileUrl = supaClient.storage
.from('training-files')
.getPublicUrl(result.data.path)
console.log('文件URL:', fileUrl)
}
6. 认证操作
// 登录
const result = await supaClient.signInWithPassword(email, password)
// 登出
await supaClient.signOut()
// 获取当前会话
const session = supaClient.getSession()
// 获取当前用户
if (session && session.user) {
const userId = session.user.id
const userEmail = session.user.email
}
错误处理
try {
const result = await supaClient
.from('ak_training_projects')
.select('*')
.execute()
if (result.success) {
// 处理成功结果
this.projects = result.data
} else {
// 处理错误
uni.showToast({
title: result.message || '操作失败',
icon: 'none'
})
}
} catch (error) {
console.error('请求失败:', error)
uni.showToast({
title: '网络错误',
icon: 'none'
})
}
数据安全访问
使用 types.uts 中的安全访问函数:
import { safeGet } from '../types.uts'
// 安全获取数据
const projectId = safeGet(project, 'id', '') as string
const projectName = safeGet(project, 'name', '未命名项目') as string
const difficulty = safeGet(project, 'difficulty', 1) as number
最佳实践
- 统一错误处理 - 使用 try-catch 包装所有数据库操作
- 数据验证 - 在插入/更新前验证数据有效性
- 实时订阅管理 - 在页面卸载时记得取消订阅
- 安全访问 - 始终使用
safeGet等安全函数访问数据 - 性能优化 - 合理使用
limit()和分页查询
示例页面
参考 pages/sport/student/simple-records.uvue 查看完整的实现示例。
总结: 删除了 api.uts 包装层后,直接使用 supaClient 链式调用让代码更加简洁、直观和高效!