封装webSQL(七)封装 分页和查询
2021-07-29 本文已影响0人
自然框架
虽然现在分页的方式多种多样,不像以前只能按页翻,但是基础原理还是一样的。
webSQL的分页比较简单(不考虑性能的前提下),因为可以使用limit。
SQL
select * from table where xxx order by xxxx limit 0,10
封装
/**
* 分页获取数据,可以查询
* @param { MySQLHelp } help 访问数据库的实例
* @param { Object } meta 表、字段
* @param { Object } query 查询条件
* @param { Object } pager 数据
* @returns 添加记录的ID
* * meta 结构:
* * * tableName: '', 表名
* * * cols:{colName: '类型'}, 需要显示的字段
* * query 结构(查询条件):
* * * { colName: [401, 11] } 字段名称,查询方式,查询关键字
* * pager 结构:
* * * pageSize: 20 // 一页显示多少条记录
* * * orderBy: { id: false } // 排序字段:字段名,false表示倒序。
* * * pageTotal: 100 // 符合查询条件的总记录数
* * * pageIndex: 1 // 显示第几页的记录,从 1 开始
*/
export default function getPager (help, meta, query, pager) {
console.log('开始分页 :')
const myPromise = new Promise((resolve, reject) => {
// 查询条件和查询参数
const { whereQuery, whereValue } = help._getWhereQuery(query)
// 设置排序和分页
const { orderBy, limit } = help._getPager(pager)
// 设置显示的字段
const showCol = Object.keys(meta.cols)
if (showCol.length === 0) { showCol.push('*') }
// 拼接查询语句
const sql = `SELECT ${showCol.join(',')} FROM ${meta.tableName} ${whereQuery} ${orderBy} ${limit}`
console.log('select-sql:', sql, whereValue)
help.query(sql, whereValue)
.then((res) => {
// 添加成功
resolve(res.rows)
})
.catch((err) => {
// 出错了
console.log('分页获取记录失败了:', err)
reject(err)
})
})
return myPromise
}
查询方式上一篇介绍了,这里说一下分页的处理
分页
/**
* 内部函数,根据分页信息,设置 分页信息和排序字段
* @param { object } pager 分页和排序
* @returns order by 和 limit
*/
_getPager (pager) {
let _limit = '' // 分页,可以不设置
let _order = '' // 排序,可以不设置
// 设置分页 order by 和 limit
if (typeof pager !== 'undefined') {
if (typeof pager.pagerIndex !== 'undefined') {
// 用 limit 实现分页
const _pageSize = pager.pagerSize || 10
const index = _pageSize * (pager.pagerIndex - 1)
_limit = ` limit ${index}, ${_pageSize} `
}
if (typeof pager.orderBy === 'object') {
// 设置排序字段和方式
const arr = []
for (const key in pager.orderBy) {
const col = key
const isAsc = pager.orderBy[key] ? ' asc ' : ' desc '
arr.push(col + ' ' + isAsc)
}
_order = ' order by ' + arr.join(',')
}
}
return {
orderBy: _order,
limit: _limit
}
}
-
order by
排序字段,还是比较简单的,可以设置多个字段,字段名是key,true表示升序,false表示降序。
这样就可以把多个字段拼在一起了。 -
limit
需要根据一页的记录数和第几页计算一下,_pageSize * (pager.pagerIndex - 1)
这个是位置,然后取 _pageSize 条记录。
这样简单的分页就可以搞定了。
啥时候统计总记录数
一般的分页组件,都需要设置一个总记录数,这样便于控制页数,避免翻着翻着就翻出去了。
统计总记录数,就需要count,数据量小的话,这个统计的消耗可以忽略不计,但是如果数据量非常大的话,count占用的资源就不能忽略不计了。
那么怎么办呢?我们可以想一想,真的需要每次翻页的时候都去统计一遍总记录数吗?
如果你也觉得不是的话,那么我们来分析一下
[ ✔ ] 查询后
[ ✔ ] 添加后
[ ✔ ] 删除后
[ ✘ ] 页号翻页
查询条件改变,记录数会改变;删除后记录数也会改变;添加后也会改变总记录数,所以都需要 count 一下。剩下的虽然也有变化的可能,但是我们可以忽略不计,认为是不会变化,所以就不 count 了。
这样可以省去很多 count 操作。
实现方式
// 引入help
import { getCount, getPager } from '../../../packages/websql.js'
/**
* 实现获取记录服务
* @param {object} userInfo 当前登录人的信息
* @param {object} help 访问数据库的实例
* @param {objec} info 服务的 meta
* @param {object} pagerInfo 分页和查询信息
* @returns 返回新添加的记录的ID
*/
export default function getPager (userInfo, help, info, pagerInfo) {
return new Promise((resolve, reject) => {
console.log('\n启动 getPager 服务\n') // , info
const query = pagerInfo.query
const pager = info.pager
pager.pagerIndex = pagerInfo.pager.pagerIndex
// 返回对象
const re = {
list: [],
pager: info.pager
}
if (pagerInfo.useCount) {
// 需要统计总记录数
getCount(help, info, query).then((count) => {
// 设置总记录数
re.pager.pagerTotal = count
// 获取分页记录集
getPager(help, info, query, pager).then((list) => {
re.list = list
resolve(re)
}).catch((err) => {
reject(err) // '获取分页数据出错!'
})
}).catch((err) => {
reject(err) // '获取总记录数出错!'
})
} else {
// 直接获取记录集
getPager(help, info, query, pager).then((list) => {
re.list = list
resolve(re)
}).catch((err) => {
reject(err) // '获取分页数据出错!'
})
}
})
}
这里没有用 await ,虽然代码多了一点,但是还算可以吧。