测试需求平台10-DBUtils 优化数据连接与 SQL Limit 实现分页

✍此系列为整理分享已完结入门搭建《TPM提测平台》系列的迭代版,拥抱Vue3.0将前端框架替换成字节最新开源的arco.design,其中约60%重构和20%新增内容,定位为从 0-1手把手实现简单的测试平台开发教程,内容将囊括基础、扩展和实战,由浅入深带你实现测试开发岗位中平台工具技术能力入门和提升

👨‍💻 作者:大奇 MegaQi  
✍️ 专注测试开发实战&车载方向干货分享,欢迎访问长期关注博客和公众号。

本篇将对数据库进行优化,包括链接池优化和 limit 使用技巧。

1.数据库连接优化

在项目中链接数据是直接通过 pymysql 去做的链接请求关闭,每次操作都要独立重复请求,其实是比较浪费资源,在并发不大的小项目虽然无感知,但如果有频繁请求的项目中,就会有性能问题,那么可以通过使用连接池技术,管理来进行优化

1.1 Python DBUntils

DBUnitls 是一套 Python 的数据库连接池包,对链接对象进行自动链接和释放,提高高频高并发下数据访问性能,大概的原理如:

DBUntils 按照配置初始化多个数据库连接存储在连接池中

  • 在程序创建连接的时候,从空闲的连接池中获取,不需要重新初始化连接,提升链接速度;

  • 在程序使用完毕后,把连接放回连接池,并不真正地关闭,等待其他请求使用,减少频繁数据的打开和关闭操作。

DBUntils 提供两种方式,并都能自动管理

  • PersistentDB (persistent_db) 提供线程专用的连接

  • PooledDB (pooled_db) 提供线程间可共享的连接

官方 [注解-1] 给出的示意图如下,仅够参考下,不进行扩展

使用此功能需要安装依赖 pip install DBUtils ,一般比较常用就是共享的方式,以 pooled_db 为例子,使用方法很简单

import pymysqlfrom dbutils.pooled_db import PooledDB# 初始化数据库连接,使用pymysql连接,pool = PooledDB(pymysql,3,host='',port='',user='',passwd='',database='')
# 一般连接db = pool.connection()cur = db.cursor()cur.execute(...)res = cur.fetchone()cur.close() # 关闭使用游标db.close() # 关闭使用连接
# 或者通过with方式with pool.connection() as db:    with db.cursor as cur:        cur.execute(...)       res = cur.fetchone()

一些参数说明,上边说明中第一参数为 creator 指定那种连接模式,第二参数为 mincached

  • mincached :启动时开启的空的连接数量

  • maxcached :连接池最大可用连接数量

  • maxshared : 连接池最大可用共享连接数量

  • maxconnections : 最大允许连接数量

  • maxusage :单个丽娜姐最大复用次数

  • blocking :达到最大数量时是否阻塞

这里只是对连接的管理,DBUntils 的基本知识点讲完了,关于性能对比可以网上搜索相关内容,另外其他的数据库操作还按照自己使用方法进行操作即可。

1.2 实例改造

以已经实现的 product.py 查询列表接口做一个实际改改造,具体的应用会在后边的需求实现中体现。

from dbutils.pooled_db import PooledDB
+ pool = PooledDB(pymysql, mincached=2, maxcached=5,host=config.MYSQL_HOST, port=config.MYSQL_PORT,+                 user=config.MYSQL_USER, passwd= config.MYSQL_PASSWORD, database=config.MYSQL_DATABASE,+                 cursorclass=pymysql.cursors.DictCursor)
@app_product.route("/api/product/list", methods=['GET'])def product_list():-    # 初始化数据库链接-    connection = connectDB()+    # 使用连接池链接数据库+   connection = pool.connection()    # 使用python的with..as控制流语句(相当于简化的try except finally)    with connection.cursor() as cursor:        # 查询产品信息表-按更新时间新旧排序        sql = "SELECT * FROM `products` WHERE `status`=0 ORDER BY `update` DESC"        cursor.execute(sql)        data = cursor.fetchall()
    # 按返回模版格式进行json结果返回    resp_data = {        "code": 20000,        "data": data    }

2.SQL 中 limit

2.1 基础知识

项目中对于较多的数据显示,需要实现分页数据查询,这可以利用 SQL 语法关键词 limit ,它可以限制查询结果返回的数量,也可以指定起始索引,来完成分页查询效果,语法形式与参数解释:

  • i:指定。一个返回记录行的偏移量(可省略即表示从 0 开始)

  • n:第二个参数指定返回记录行的最大数目

# 基本用法SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
# 简化形式select * from tableName limit i,n

两个示例如:

... limit 10 # 查询前10条数据, 也可以表示为limit 0,10... limit 10,15 # 从11条开始返回后15条数据 即11-25

这里有个 注意事项,网上好多关于 limit 最后一个参数用 -1 可以表示,指定偏移量到最后,这个目前在新的 MYSQL 版本已经无效,会报语法错误,办法是用个较大的数代替。

如何实现分页查询,通过观察我们可以这样,如果前端传递的 page 页数(初始为 1),每页的数量为 page_size,那么第一个参数计算偏移量可设置为 (page-1) * page_size,第二参数表可设置为page_size, 例如 前端请求第一页 20 个,则计算后后两个参数为( 0, 20),再如请求第 2 页 20 个,则计算后两个参数为 ( 20, 20 ),这样就可以实现分页数据查询效果。

2.2 实践案例

具体案例这里截图一张后边实现提测需求查询,通过参数 size,page 计算 limit 参数实现分页的数据查询逻辑。

这个知识点最后,扩展一个小优化,如果是分页数据特别,第一个参数偏移量太大的时候会带来性能的问题,优化的方式是使用子查询优化(前提条件是有自增 ID 的表),即先通过查询偏移量 ID,然后条件 “>=ID + limit 数量" 进行查询。

SELECT * FROM apps where id >=(SELECT id FROM apps LIMIT 100000,1) LIMIT 20

复制代码

3 Moment.js

JavaScript 日期处理类库( http://momentjs.cn/ ),它提供了一些经常用的时间处理方法,在 node.js 和 浏览器中都可以直接使用。

3.1 安装和使用

在我们前端项目中安装和引用如下:

# 终端安装依赖(笔者测试的最新版本为2.24.0)npm install moment
# 导入依赖import moment from "moment";

也可通过 require 定义,或 html 直接引用

// require定义var moment = require('moment');moment().format();
// 浏览器script引用<script src="moment.js"></script><script>    moment().format();</script>

3.2 常用方法

3.2.1 格式化时间

通过 format('字符串') 对日期进行格式化。

// 默认locale语言为cnmoment().format('MMMM Do YYYY, h:mm:ss a'); // August 13th 2022, 2:19:01 pmmoment().format('dddd');                    // Saturdaymoment().format("MMM Do YY");               // Aug 13th 22
// 更改本地语言为简体中文moment.locale('zh-cn')const res = moment().format('YYYY-MM-DD HH:mm'); // 2022-08-13 14:32

格式字符串很多,可以根据需要自行组合

http://momentjs.cn/docs/#/displaying/format/

3.2.2 相对时间

通过fromNowtoNowto等方法计算相对时间

// 当前时间与北京奥运开幕时间  xx年前moment("20080808", "YYYYMMDD").fromNow();
// 到现在为止已距当天/小时已经过去moment().startOf('day').fromNow();        // xx 小时前moment().startOf('hour').fromNow();       // xx 分钟前
// 到现在为止已距当天/小时结束还有moment().endOf('day').fromNow()       // xx 小时后moment().endOf('hour').fromNow()      // xx 分钟后
// toNow与fromNow给出相反的间隔moment([2008,8,8]).toNow() // xx 年后
// to用户两个时间的对比const start = moment([2022, 8, 11]);const end = moment([2022, 8, 13]);console.log(end.to(start))  // 2 天前console.log(start.to(end))  // 2 天后
3.2.3 时间计算

subtract() 通过减去时间来改变原始的 momentadd() 通过增加时间来改变原始的 momentstartOf() / endOf() 通过将原始的 moment 设置为时间单位的开头/末尾来对其进行更改注:以上计算本身还是 moment 如果项展示还需要借助formatcalendar

// 减去响应的天数console.log(moment().subtract(10, 'days')) console.log(moment().subtract(10, 'days').format("YYYY-MM-DD"))console.log(moment().subtract(10, 'days').calendar())
// 已2022年8月13日 13时测试结果如下// Moment<2022-08-03T15:01:51+08:00>// 2022-08-03// 2022/08/03     // 同样测试时间天数加法console.log(moment().add(7, 'days').calendar())    // 2022/08/20console.log(moment().add(1, 'months').calendar())  // 2022/09/13console.log(moment().add(10, 'years').calendar())  // 2032/08/13
// 举例当月的开始和结束天console.log(moment().startOf('month').calendar())console.log(moment().endOf('months').calendar())

对于moment.js 以上是大奇认为比较常用的一些方法,还有更多的用法方便在时间上的快捷操作,按照项目需要随用随事到官方查看使用文档即可。

本篇主要讲解了几个后边要用到扩展知识点,在当今的开发环境生态下,有很多类似这样好用的前后端开发工具包,我们要善于发现和利用它们,尽量避免无效重复造轮子,把时间花费在功能实现上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/512586.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2191. 数字梯形问题(网络流,费用流,最大权不相交路径)

活动 - AcWing 给定一个由 n 行数字组成的数字梯形如下图所示。 梯形的第一行有 m 个数字。 从梯形的顶部的 m 个数字开始&#xff0c;在每个数字处可以沿左下或右下方向移动&#xff0c;形成一条从梯形的顶至底的路径。 规则 1&#xff1a;从梯形的顶至底的 m 条路径互不相…

隧道技术和代理技术(一)

目录 基础知识 单机-防火墙-限制协议出入站 域控-防火墙-组策略对象同步 域控-防火墙-组策略不出网上线 基础知识 -隧道技术&#xff1a;解决不出网协议上线的问题&#xff08;利用出网协议进行封装出网&#xff09; -代理技术&#xff1a;解决网络通讯不通的问题&#xf…

职场卷王:我用可视化大屏模板做工作汇报,惊艳了同事和领导。

2023结束了&#xff0c;我和我的小伙伴们纷纷开始忙碌的年终总结和汇报。 正忙着汇总Excel数据、写word讲稿、找PPT模板时&#xff0c;我发现隔壁组的老王独自在大会议室偷偷调试起了那台汇报用的电视机。 不会吧不会吧&#xff0c;年终汇报还有一周呢&#xff0c;这家伙PPT都…

web组态--新一代全流程低代码物联网平台

先上图&#xff0c;实际完成效果&#xff1a; 1.添加应用图纸 登录by组态后台&#xff1a;http://www.byzt.net:90 ​ 点击组态管理-画面管理&#xff0c;先新建一个组态画面&#xff0c;填写画面名称&#xff0c;保存&#xff0c;进入组态画面。 ​ 选择画面管理&#xff…

mysql高可用架构设计

一、主从架构 主从架构一般如下所示 这里从节点一般设置成只读&#xff08;readonly&#xff09;模式。这样做&#xff0c;有以下几个考虑&#xff1a; 有时候一些运营类的查询语句会被放到备库上去查&#xff0c;设置为只读可以防止误操作&#xff1b; 防止切换逻辑有 bug&a…

MySQL:一行记录如何

1、表空间文件结构 表空间由段「segment」、区「extent」、页「page」、行「row」组成&#xff0c;InnoDB存储引擎的逻辑存储结构大致如下图&#xff1a; 行 数据库表中的记录都是按「行」进行存放的&#xff0c;每行记录根据不同的行格式&#xff0c;有不同的存储结构。 页…

微服务架构 | 多级缓存

INDEX 通用设计概述2 优势 通用设计概述 通用设计思路如下图 内容分发网络&#xff08;CDN&#xff09; 可以理解为一些服务器的副本&#xff0c;这些副本服务器可以广泛的部署在服务器提供服务的区域内&#xff0c;并存有服务器中的一些数据。 用户访问原始服务器时&#x…

Kafka | SpringBoot集成Kafka

SpringBoot集成Kafka 一、前言二、项目1. pom2. application.properties4. 消息生产者-测试5. 消息消费者 三、启动测试四、有总结的不对的地方/或者问题 请指正, 我在努力中 一、前言 该文章中主要对SpringBoot 集成Kafka 主要是 application.properties 与 pom坐标就算集成完…

【无刷电机学习】光耦HCNR200基本原理及应用(资料摘抄)

【仅作自学记录&#xff0c;不出于任何商业目的。如有侵权&#xff0c;请联系删除&#xff0c;谢谢&#xff01;】 本文摘抄翻译自&#xff1a; https://docs.broadcom.com/wcs-public/products/application-notes/application-note/331/6/av02-1333en-an_5394-16jul10.pdfhtt…

ruoyi-vue-plus4.X版本实现内嵌swagger文档(简单解决方法)

1.在common模块中添加pom依赖 <dependency><groupId>org.webjars</groupId><artifactId>swagger-ui</artifactId><version>4.15.5</version></dependency>结果如下&#xff1a; 2.在ResourcesConfig配置类的addResourceHandl…

打家劫舍(java版)

&#x1f4d1;前言 本文主要是【动态规划】——打家劫舍(java版)的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一…

LeetCode.232. 用栈实现队列

题目 232. 用栈实现队列 分析 先了解一下栈和队列的特点&#xff1a; 栈&#xff1a;先进后出队列&#xff1a;先进先出 想用栈实现队列的特点&#xff0c;就需要使用两个栈。因为两个栈就可以将列表倒序。 假设第一个栈 s1 [1,2,3]&#xff0c;第二个栈 s2 [] 。若循环…