Qt数据库应用之实现通用数据库分页

目录
  • 一、前言
  • 二、功能特点
  • 三、体验地址
  • 四、效果图
  • 五、相关代码

一、前言

数据库分页展示,在所有的涉及到数据库记录的项目中都是需要的,除了简单的设备信息表、用户信息表这种很少几条几十条数据量的表除外,其余的日志记录表等都需要分页展示数据,少量的数据可以滚动条下拉查看完,超过百条以上的一般建议要加上分页的功能处理,不然用户查看起来明显不舒服,体验不友好,最明显的例子就是网页的搜索结果,一次性展示上万条,不仅是多余的增加了查询的压力,而且用户往往只关注最前面的几页记录,再比如查询报警记录,一般是按照时间降序排序,最近最新的报警记录显示在最前面,用户最关心的也就是最前面的结果。

数据库分页一般是通过sql语句的limit去处理,根据用户选择的条件构建sql语句传入数据库执行,每当单击上一页、下一页、第一页、末一页等按钮的时候,也是重新执行了sql语句返回结果。最开始这个数据库分页类是将分页按钮都集中在一起,后面单独拆分了出来,逻辑代码一个类,界面单独成分页导航控件专门展示UI外观,这个外观可以设置各种颜色和样式等。

数据库通用翻页类特点:

  1. 可设置每页多少行记录,自动按照设定的值进行分页。
  2. 可设置要查询的表名、字段集合、条件语句、排序语句。
  3. 可设置第一页、上一页、下一页、末一页、翻页按钮。
  4. 可设置当前页、总页数、总记录数、每页记录数、查询用时标签页。
  5. 多线程查询总记录数,数据量巨大时候不会卡主界面。
  6. 建议条件字段用整型类型的主键,速度极快。
  7. 提供查询结果返回信号,包括当前页、总页数、总记录数、查询用时等信息。
  8. 可设置所有列或者某一列对齐样式例如居中或者右对齐。
  9. 可增加列用于标识该条记录,设定列的位置、标题、宽度。
  10. 提供函数直接执行第一页、上一页、下一页、末一页。
  11. 提供函数直接跳转到指定页。
  12. 根据是否第一页、末一页自动禁用对应的按钮。
  13. 本控件是翻页功能类,和翻页控件navpage完美搭配,形成超级牛逼的翻页控件。

分页导航控件特点:

  1. 可设置页码按钮的个数。
  2. 可设置字体大小。
  3. 可设置边框圆角角度、大小、颜色。
  4. 可设置正常状态背景颜色、文字颜色。
  5. 可识别悬停状态背景颜色、文字颜色。
  6. 可设置按下状态背景颜色、文字颜色。
  7. 可设置选中状态背景颜色、文字颜色。
  8. 可设置导航位置居中对齐、左对齐、右对齐。
  9. 可设置是否显示提示标签控件。
  10. 自动计算总页码数显示隐藏多余按钮。
  11. 自动计算切换页码导航。
  12. 和分页导航功能类无缝对接完美融合。

关于Qt数据库相关开发的一些经验总结

二、功能特点

同时支持多种数据库比如odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金仓等。

一个数据库类即可管理本地数据库通信,也支持远程数据库通信等。

数据库线程支持执行各种sql语句,包括单条和批量。

组件中的所有类打印信息、错误信息、执行结果都信号发出去。

集成数据库通用翻页类(负责具体处理逻辑),搭配分页导航控件(负责外观),形成超级牛逼的翻页控件。

集成数据库自动清理类,设定最大记录数后台自动清理早期数据。

集成自定义委托类,支持复选框、文本框、下拉框、日期框、微调框、进度条等。

同时支持Qt4-Qt6,亲测Qt4.6到Qt6.3任意版本,任意系统和编译器。

本组件无故障 360天7乘24小时 运行在至少上万个现场,商业级别品质保证。

每个类都对应完整详细的使用示例,注释详细,非常适合阅读学习。

可以作为独立的程序运行,比如自动清理早期数据,同步数据到云端。

全部线程处理,不卡界面,自动重连数据库。

普通测试情况,sqlite数据库,数据库发生器每秒钟插入1000条记录约0.003秒钟,同时自动清理数据类每秒钟删除1000条记录约0.13秒,不同线程互不干扰。

三、体验地址

体验地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg  提取码:uyes 文件名:bin_dbtool.zip

国内站点:https://gitee.com/feiyangqingyun

国际站点:https://github.com/feiyangqingyun

四、效果图

五、相关代码

#include "frmdbpage.h"
#include "ui_frmdbpage.h"
#include "quihelper.h"
#include "dbconnthread.h"
#include "dbpage.h"
#include "dbdelegate.h"

frmDbPage::frmDbPage(QWidget *parent) : QWidget(parent), ui(new Ui::frmDbPage)
{
    ui->setupUi(this);
    this->initForm();
    this->initConfig();
}

frmDbPage::~frmDbPage()
{
    delete ui;
}

void frmDbPage::initForm()
{
    ui->frame->setFixedWidth(AppConfig::RightWidth);
    QUIHelper::initTableView(ui->tableView);

    //实例化数据库通信类
    dbConn = new DbConnThread(this);
    dbConn->setDbFlag("分页");

    //实例化翻页类
    dbPage = new DbPage(this);
    //关联查询记录总数
    connect(dbConn, SIGNAL(receiveCount(QString, int, int)), dbPage, SLOT(receiveCount(QString, int, int)));

    dbPage->setAllCenter(true);
    dbPage->setRecordsPerpage(30);
    dbPage->setWhereSql("where 1=1");

    //分页导航控件
    connect(ui->navPage, SIGNAL(selectPage(int)), dbPage, SLOT(selectPage(int)));
    connect(dbPage, SIGNAL(receivePage(quint32, quint32, quint32, quint32)),
            ui->navPage, SLOT(receivePage(quint32, quint32, quint32, quint32)));
    QLabel *labInfo = ui->navPage->getLabInfo();
    QList<QPushButton *> btns = ui->navPage->getBtnAll();
    dbPage->setControl(ui->tableView, ui->labPageTotal, 0, ui->labRecordsTotal, 0, ui->labSelectTime,
                       labInfo, btns.at(0), btns.at(1), btns.at(2), btns.at(3));

    //采用系统默认的样式并设置按钮固定尺寸
    ui->navPage->setShowStyle(false);
    ui->navPage->setShowGoPage(true);
    foreach (QPushButton *btn, btns) {
        btn->setFixedWidth(50);
    }
}

void frmDbPage::initConfig()
{
    ui->cboxDbType->addItems(DbHelper::getDbType());
    ui->cboxDbType->setCurrentIndex(ui->cboxDbType->findText(AppConfig::DbType4));
    connect(ui->cboxDbType, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));

    ui->txtDbName->setText(AppConfig::DbName4);
    connect(ui->txtDbName, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtHostName->setText(AppConfig::HostName4);
    connect(ui->txtHostName, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtHostPort->setText(QString::number(AppConfig::HostPort4));
    connect(ui->txtHostPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtUserName->setText(AppConfig::UserName4);
    connect(ui->txtUserName, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtUserPwd->setText(AppConfig::UserPwd4);
    connect(ui->txtUserPwd, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));

    ui->txtColumnName->setText(AppConfig::ColumnName4);
    connect(ui->txtColumnName, SIGNAL(textChanged()), this, SLOT(saveConfig()));

    ui->txtColumnWidth->setText(AppConfig::ColumnWidth4);
    connect(ui->txtColumnWidth, SIGNAL(textChanged()), this, SLOT(saveConfig()));

    ui->txtCountName->setText("LogID");
    ui->txtOrderSql->setText("LogID asc");
}

void frmDbPage::saveConfig()
{
    AppConfig::DbType4 = ui->cboxDbType->currentText();
    AppConfig::DbName4 = ui->txtDbName->text();
    AppConfig::HostName4 = ui->txtHostName->text();
    AppConfig::HostPort4 = ui->txtHostPort->text().toInt();
    AppConfig::UserName4 = ui->txtUserName->text();
    AppConfig::UserPwd4 = ui->txtUserPwd->text();

    AppConfig::ColumnName4 = ui->txtColumnName->toPlainText();
    AppConfig::ColumnWidth4 = ui->txtColumnWidth->toPlainText();
    AppConfig::writeConfig();
}

void frmDbPage::on_btnOpen_clicked()
{
    if (ui->btnOpen->text() == "打开数据库") {
        DbInfo dbInfo;
        dbInfo.connName = this->objectName();
        dbInfo.dbName = AppConfig::DbName4;
        dbInfo.hostName = AppConfig::HostName4;
        dbInfo.hostPort = AppConfig::HostPort4;
        dbInfo.userName = AppConfig::UserName4;
        dbInfo.userPwd = AppConfig::UserPwd4;

        QString dbType = AppConfig::DbType4.toUpper();
        if (dbType == "SQLITE") {
            dbInfo.dbName = DbHelper::getDbDefaultFile();
        }

        dbConn->setConnInfo(DbHelper::getDbType(dbType), dbInfo);
        if (dbConn->openDb()) {
            dbConn->start();
            ui->btnOpen->setText("关闭数据库");
        } else {
            QString error = dbConn->getDatabase().lastError().text();
            QUIHelper::showMessageBoxError("打开数据库失败!\n" + error, 3);
        }
    } else {
        dbConn->stop();
        dbConn->closeDb();
        ui->btnOpen->setText("打开数据库");
        dbPage->clear();
    }

    QTimer::singleShot(100, this, SLOT(getTables()));
    QTimer::singleShot(1000, this, SLOT(on_btnDo_clicked()));
}

void frmDbPage::on_btnCopy_clicked()
{
    //将数据库设置参数一键粘贴过来
    ui->cboxDbType->setCurrentIndex(ui->cboxDbType->findText(AppConfig::LocalDbType));
    ui->txtDbName->setText(AppConfig::LocalDbName);
    ui->txtHostName->setText(AppConfig::LocalHostName);
    ui->txtHostPort->setText(QString::number(AppConfig::LocalHostPort));
    ui->txtUserName->setText(AppConfig::LocalUserName);
    ui->txtUserPwd->setText(AppConfig::LocalUserPwd);
}

void frmDbPage::getTables()
{
    if (!dbConn->getOk()) {
        return;
    }

    //取出数据库对应的表集合
    QStringList tables = dbConn->getDatabase().tables();
    ui->cboxTables->clear();
    ui->cboxTables->addItems(tables);
    if (tables.contains("LogInfo")) {
        ui->cboxTables->setCurrentIndex(ui->cboxTables->findText("LogInfo"));
    }
}

void frmDbPage::on_btnDo_clicked()
{
    if (!dbConn->getOk()) {
        return;
    }

    //表格字段 名称+宽度
    QList<QString> columnNames = AppConfig::ColumnName4.split(",");
    QList<int> columnWidths;
    QStringList listWidth = AppConfig::ColumnWidth4.split(",");
    foreach (QString width, listWidth) {
        columnWidths << width.toInt();
    }

    //具体函数解释参见对应类头文件
    //不设置字段中文名和宽度也行,默认取数据库字段名
    dbPage->setColumnNames(columnNames);
    dbPage->setColumnWidths(columnWidths);

    dbPage->setDbType(AppConfig::DbType4);
    dbPage->setConnName(dbConn->getDatabase().connectionName());

    QString tableName = ui->cboxTables->currentText();
    QString countName = ui->txtCountName->text();
    QString orderSql = ui->txtOrderSql->text();
    dbPage->setTableName(tableName);
    dbPage->setOrderSql(orderSql);

    dbPage->select();
    dbConn->selectCount(tableName, countName, "where 1=1");
}

void frmDbPage::on_cboxTables_currentIndexChanged(int)
{
    QString table = ui->cboxTables->currentText();
    QSqlRecord records = dbConn->getDatabase().record(table);
    ui->cboxRecords->clear();
    for (int i = 0; i < records.count(); ++i) {
        ui->cboxRecords->addItem(records.fieldName(i));
    }
}

void frmDbPage::on_cboxRecords_currentIndexChanged(int)
{
    QString record = ui->cboxRecords->currentText();
    ui->txtCountName->setText(record);
    ui->txtOrderSql->setText(record + " asc");
}

到此这篇关于Qt数据库应用之实现通用数据库分页的文章就介绍到这了,更多相关Qt通用数据库分页内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Qt数据库应用之实现通用数据库清理

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 很多项目如果需要存储很多日志记录比如运行日志,时间长了记录数量非常多,数据库体积不断增大,对应数据库表的增删改查的效率不断降低,为了消除这几个影响,需要有一套机制,不断将早期的数据清理,清理的规则比如可以指定表名.字段名.时间范围等. 日志记录的清理一方面是为了保证查询效率,毕竟数据量大了明显影响查询速度,一方面也是为了节约磁盘存储空间,毕竟存储空间有限,尤其是嵌入式板子,容量一般不会很大,记录无限制的存储下去会不断

  • Qt数据库应用之实现通用数据生成器

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 有两种应用场景需要用到数据生成器,一种是需要测试数据库性能,比如在100万条和1000万条记录的时候对比查询或更新语句执行耗时,一种是随机模拟生成一堆数据,用来测试程序的性能,看下程序中到了百万千万级别的数据量的时候,程序的代码执行是否受影响,影响有大等.很多人觉得sqlite数据库性能超过几十万就不行,于是亲自用这个数据发生器随机模拟生成了一亿条记录,测试下来发现性能有损失,但是不像传说中的垃圾,起码还是完全可用的

  • Qt数据库相关应用开发总结

    目录 一.前言 二.数据库开发经验总结 三.数据库连接说明 四.数据库操作流程代码 五.数据库综合应用组件 一.前言 近期花了两个多月时间,将数据库相关的代码重新封装成了各种轮子(这条路必须打通,打通以后,相关项目只需要引入这个组件pri即可),测试了从Qt4.7到Qt6.1的各种版本,测试了odbc.sqlite.mysql.postgresql.sqlserver.oracle.人大金仓等数据库,测试了本地连接.远程连接.阿里云连接等,测试了windows.linux.mac等系统,将所有项

  • Qt数据库应用之实现数据图文混排

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 除了能够打印基本的文字信息数据到pdf和纸张,越来越多的应用需求还要求能够导出图片,并且要支持图文混排,相当于doc文档类似,当然也不会是太复杂的,类似于打印报表一样,有表格形式的文字描述,也有对应的图片插入其中,图文混排的应用场景还真不少比如医疗行业输出诊断结果往往都带了图片.于是针对这个需求特意开辟了新的类DataCreat专门生成报表的数据,将生成好的数据体直接传入给DataPrint类即可,如果有各种各样的不

  • Qt数据库应用之数据打印到pdf

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 自从数据可以导出到xls,又有客户提出了不同的需求,比如既然可以将数据导出到xls,那是否可以导出到pdf文件呢?因为xls打开以后用户可以修改数据造假之类的,而pdf默认是不可编辑的,除非借助专业的工具,所以如果想要限定用户导出数据不能被更改,那导出pdf是最佳选择.写程序往往都是这样,一步步慢慢增加,随着用户需求的增加,程序量也越来越多,轮子组件也越来越多.往往客户提需求的时候,一定要认真聆听,尤其是一线用户,实

  • Qt数据库应用之实现数据的导入与导出

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 在经历过大大小小十几个甚至几十个纯QtWidget项目后,涉及到数据库相关的项目,几乎都有一个需求,将少量的信息数据比如设备信息.防区信息等,导出到文件保存好,然后用户可以打开该表格进行编辑,编辑完成后保存,再重新导入到软件中,这样相当于安排专人录入数据,而不是在软件中一个个新增效率低了些,甚至有些软件运行在嵌入式板子上或者一些特殊场景,不大方便现场添加编辑信息,如果是提供模板之类的让用户添加好,然后再一次性导入,这

  • Qt数据库应用之实现数据打印到纸张

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 数据能够打印到pdf文件,当然可以打印到纸张,而且使用qprinter默认就是打印到纸张的,上一篇文章写得功能是打印到pdf,其实还要单独特殊设置打印到文件,并指定格式为pdf.不指定输出文件和格式默认就是打印到纸张,关于Qt打印内容到纸张,网上的办法非常多,比如有些直接用painter绘制,逐步控制分页打印,个人还是喜欢html格式的内容传入,因为html格式相当灵活,可控范围相当大,而且整齐,甚至可以先直接输出到

  • Qt数据库应用之实现通用数据库分页

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 数据库分页展示,在所有的涉及到数据库记录的项目中都是需要的,除了简单的设备信息表.用户信息表这种很少几条几十条数据量的表除外,其余的日志记录表等都需要分页展示数据,少量的数据可以滚动条下拉查看完,超过百条以上的一般建议要加上分页的功能处理,不然用户查看起来明显不舒服,体验不友好,最明显的例子就是网页的搜索结果,一次性展示上万条,不仅是多余的增加了查询的压力,而且用户往往只关注最前面的几页记录,再比如查询报警记录,一般

  • Qt数据库应用之实现通用数据库采集

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 数据库采集对应的就是上一篇文章的数据库同步,数据库同步到云端数据库以后,app.网页.小程序啥的要数据的话,可以通过执行http请求拿到数据,http接收应答这边程序一般最简单可以用php写,几行代码即可,比如根据请求的参数构建需要执行的sql语句,执行以后将结果json形式返回即可. 通过Qt程序去做数据库采集有多种方式,即可直接连接数据库然后绑定数据库表到QSqlTableModel,然后不断调用select方法

  • Qt数据库应用之实现通用数据库请求

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 数据库请求是在数据库采集的基础上,换成http请求的形式来获取数据,这样就脱离了数据库组件,而采用的通用的http请求的形式从数据库拿数据库,这个通用性就非常广泛了,比如对方用java采集到设备的数据存入数据库,另外一个区域是用的c#采集的数据入库,然后统一规则统一规范约定一个请求机制,定时器或者线程取执行请求,拿到的json数据,挨个取出来结果,数组集合的方式发信号出去. 之前写过的可视化大屏电子看板程序,采用的也

  • Access 2000 数据库 80 万记录通用快速分页类

    代码本人优化过,测试通过 主要思路: 用一条语句统计(Count)出记录数(而不在查询时获得 RecordCount 属性), 缓存在 Cookies 中, 跳转时就不用再次统计. 使用 ADO 的 AbsolutePage 属性进行页面跳转即可. 为方便调用而写成类, 代码主要地方已有说明 硬件环境: AMD Athlon XP 2600+, 256 DDR 软件环境: MS Windows 2000 Advanced Server + IIS 5.0 + Access 2000 + IE 6

  • SQL Server中通用数据库角色权限的处理详解

    前言 安全性是所有数据库管理系统的一个重要特征.理解安全性问题是理解数据库管理系统安全性机制的前提. 最近和同事在做数据库权限清理的事情,主要是删除一些账号:取消一些账号的较大的权限等,例如,有一些有db_owner权限,我们取消账号的数据库角色db_owner,授予最低要求的相关权限.但是这种工作完全是一个体力活,而且是吃力不讨好,而且推进很慢.另外,为了管理方便和细化,我们又在常用的数据库角色外,新增了6个通用的数据库角色. 如下截图所示. 另外,为了减少授权工作量和一些重复的体力活,我们创

  • Qt数据库应用之通用数据库同步

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 数据库同步的主要功能是将本地的数据库记录同步到远程的数据库,其中数据库类型不限,比如本地是sqlite数据库,远程可以是mysql数据库,本地是mysql数据库,远程也可以是postgresql数据库,只要数据库设置的时候设定好就行.这样做相当于就是通过程序的方式将数据库记录上传同步,还有一种机制是通过直接数据库上设置热备份啥的,个人还是习惯通过程序的方式,自主可控,比如可以自定义同步哪个表,哪部分数据需要同步. 有

  • 初识通用数据库操作类——前端easyui-datagrid,form(php)

    初识通用数据库操作类--前端easyui-datagrid,form(php),实现代码比较简单,具体实现步骤请看下文. 实现功能: 左端datagrid显示简略信息,右侧显示选中行详细信息,数据库增删改 (1)点击选中行,右侧显示详细信息,其中[新增].[修改].[删除]按钮可用,[保存]按钮禁用 (2)点击[新增]按钮,[修改],[删除]按钮禁用,[保存]按钮启用 (3)点击[修改]按钮,[新增],[删除]按钮禁用 难点:通用数据库操作类中insert方法跟update方法 最终效果图: 前

  • ADO.NET通用数据库访问类

    本文实例为大家分享了ADO.NET通用数据库访问类,供大家参考学习,具体内容如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; namespace Test { public class DBHelper { publ

随机推荐