QT——操作数据库03

2023-10-27

一、安装数据库

一般使用mysql或者sqlite。

在这里插入图片描述

2. 将两个压缩包解压后的文件都放到刚刚新建的bin文件夹下
在这里插入图片描述

3. 增加path环境变量
在这里插入图片描述

在这里插入图片描述
4.验证
在这里插入图片描述

二、连接数据库

sql操作简单封装例子(单例模式)

(一)在项目的pro文件中增加一行代码

在这里插入图片描述

#表示项目使用sql
QT       +=sql

(二)连接sqlite

注意:连接sqlite 这里有个坑,就算连接sqlite失败,他也会认为你连接成功,等进行crud时就会失败。

bool bl = m_db.open();
if(!bl)
{
    qDebug() << m_db.lastError().text();
    return;
}
else
{
	// 这个代码可能会误导你
    qDebug() << "数据库连接成功了...";
}
#include "mainwindow.h"
#include <QApplication>
#include <QString>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QDebug>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    //1.根据驱动获取数据库操作实例
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    //2.加载数据源
    db.setHostName("localhost");
    //如果没有这个数据库那么会创建,如果存在,那么不会创建
    db.setDatabaseName("qt_test.db");
    // 3. 连接数据库
    bool bl = db.open();
    if(!bl)
    {
        qDebug() << db.lastError().text();
    }
    else
    {
        //注意:这个连接成功不能作为正真连接成功数据的标准。如果能操作数据库才算连接成功
        qDebug() <<db.databaseName() <<"数据库连接成功了...";
    }

    QSqlQuery query;
    //创建表
    query.exec("create table addres(id int primary key, name varchar);");

    //插入
    query.prepare("INSERT INTO addres (id, name) "
                "VALUES (:id, :name)");
    query.bindValue(":id", 1002);
    query.bindValue(":name", "上海");
    query.exec();

    //查询
    query.exec("select id,name from addres");
    // 遍历结果集
    while(query.next())
    {
        // 从当前记录中取出各个字段的值
        qDebug() << query.value(0).toString()
                 << query.value(1).toString();
    }

    //修改
    query.prepare("update addres set name = :name where id = 1001");
    query.bindValue(":name", "广东");
    query.exec();

    //删除
    query.exec("delete from addres where id = 1002");

    //查询
    query.exec("select id,name from addres");
    
    qDebug() <<"----------";
    // 遍历结果集
    while(query.next())
    {
        // 从当前记录中取出各个字段的值
        qDebug() << query.value(0).toString()
                 << query.value(1).toString();
    }

    return a.exec();
}

- qt_test.db 创建的位置:
在这里插入图片描述
- 程序输出:
在这里插入图片描述
- 使用可视化工具查看:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(三)封装连接数据库操作

这个封装有点鸡肋。只推荐使用连接数据库的操作,对数据进行crud不推荐使用封装的方法,直接使用QSqlQuery 提供的方法即可。

  • 头文件

#ifndef SQLUTIL_H
#define SQLUTIL_H

#include <QObject>
#include <QString>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

//单例模式封装sql操作
class SqlUtil : public QObject
{
public:

    static SqlUtil *instance();

    void setDatabaseInfo(QString strDriver,QString strHostName,int port,QString strDatabaseName, QString strUserName, QString strPassWord);
    void setDatabaseInfo(QString strDriver,QString strHostName,QString strDatabaseName);
    void getDrivers();

    void initDatabase();

    void closeDatabase();

    QSqlDatabase getDb();


    /*******************************************
     * 执行Sql语句
     * 输入值:
     *       strSql 需要执行的语句 主要包括 增 删 改 操作
     * 返回值:返回执行是否成功
     *****************************************/
    bool executeSql(QString strSql);
    bool executeSql(QSqlQuery query);

    /*******************************************
     * 执行Sql语句
     * 输入值:
     *         variantlistResult 存储查询的结果
     *         strSql  需要执行的语句 查询操作
     *         iColumn 查询语句返回的列数
     *
     * 返回值: 返回查询是否成功
     *****************************************/
    bool selectData(QList<QVariantList> &variantlistResult,QString strSql,int iColumn);//查询数据

private:
    //私有化构造器
    explicit SqlUtil();
    ~SqlUtil();

    //数据库实例
    QSqlDatabase m_db;

    QString m_driver; //驱动
    QString m_strHostName;    //服务器名称
    int m_port; //端口
    QString m_strDatabaseName; //数据库名称
    QString m_strUserName;    //用户名
    QString m_strPassWord;    //密码
    //创建单例连接数据库的实例
    static SqlUtil *sqlUtil ;
};

#endif // SQLUTIL_H

  • 源文件
#include "sqlutil.h"
#include <QDebug>


//必须让单例指向null,不然会报错
SqlUtil * SqlUtil::sqlUtil = nullptr;

SqlUtil::SqlUtil()
{

}

SqlUtil::~SqlUtil()
{

}

SqlUtil *SqlUtil::instance()
{
    if(sqlUtil == nullptr)
    {
        sqlUtil = new SqlUtil();
        return sqlUtil;
    }
    else
    {
        return sqlUtil;
    }
}

void SqlUtil::setDatabaseInfo(QString strDriver,QString strHostName,int port,QString strDatabaseName, QString strUserName, QString strPassWord)
{
    m_driver = strDriver;
    m_strHostName = strHostName;
    m_port = port;
    m_strDatabaseName = strDatabaseName;
    m_strUserName = strUserName;
    m_strPassWord = strPassWord;
}

void SqlUtil::setDatabaseInfo(QString strDriver,QString strHostName,QString strDatabaseName)
{
    m_driver = strDriver;
    m_strHostName = strHostName;
    m_strDatabaseName = strDatabaseName;
}



//获取QT支持的驱动
void SqlUtil::getDrivers()
{
    QStringList ls = QSqlDatabase::drivers();
    qDebug() << "当前Qt版本支持的驱动有:"<<ls;
}

//获取操作数据库的实例
void SqlUtil::initDatabase()
{
    //mysql
    //1.获取数据库操作实例
    m_db = QSqlDatabase::addDatabase(m_driver);
    //2.加载数据源
    m_db.setHostName(m_strHostName);
    m_db.setPort(m_port);   // 如果使用的是默认端口, 可以不调用该函数
    m_db.setDatabaseName(m_strDatabaseName);
    m_db.setUserName(m_strUserName);
    m_db.setPassword(m_strPassWord);

    // 3. 连接数据库
    bool bl = m_db.open();
    if(!bl)
    {
        qDebug() << m_db.lastError().text();
        return;
    }
    else
    {
        qDebug() << "数据库连接成功了...";
    }
    // 开启事务
    //m_db.transaction();
}

void SqlUtil::closeDatabase()
{
    if(m_db.isOpen())
    {
        m_db.close();
        qDebug()<<"成功关闭数据库";
    }
    else
    {
        qDebug()<<"数据库已关闭";
    }
}

QSqlDatabase SqlUtil::getDb(){
    return m_db;
}


bool SqlUtil::executeSql(QString strSql)
{
    if(!m_db.isOpen())
    {
        //重连
        initDatabase();
        if(!m_db.isOpen())
        {
            qDebug()<<"Failed to connect to root Sql admin";
            return false;
        }
        else
        {
            qDebug()<<"successed to connect";
        }
    }
    QSqlQuery query;
    query.prepare(strSql);
    bool bExecute = query.exec();
    return bExecute;
}
bool SqlUtil::executeSql(QSqlQuery query)
{
    if(!m_db.isOpen())
    {
        initDatabase();
        if(!m_db.isOpen())
        {
            qDebug()<<"Failed to connect to root Sql admin";
            return false;
        }
        else
        {
            qDebug()<<"successed to connect";
        }
    }
    bool bExecute = query.exec();
    return bExecute;
}

bool SqlUtil::selectData(QList<QVariantList> &variantlistResult, QString strSql, int iColumn)
{
    if(!m_db.isOpen())
    {
        initDatabase();
        if(!m_db.isOpen())
        {
            qDebug()<<"Failed to connect to root Sql admin";
            return false;
        }
        else
        {
            qDebug()<<"successed to connect";
        }
    }

    QSqlQuery query;
    query.prepare(strSql);
    bool flag = query.exec();

    QVariantList variantlist;
    while(query.next())
    {
        for(int i= 0; i < iColumn; i++)
        {
            QVariant value  = query.value(i);
            variantlist.append(value);
        }
        variantlistResult.push_back(variantlist);
        variantlist.clear();
    }
    return flag;
}

  • 使用
    1. 连接数据
#include "mainwindow.h"
#include <QApplication>


//操作数据库的依赖
#include "sqlutil.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("主页");
    w.setWindowIcon(QIcon(":/mainwin/resources/wxb主页.png"));
    w.show();
    //初始化数据库
    SqlUtil *sqlUtil =  SqlUtil::instance();
    //连接sqlite
    sqlUtil->setDatabaseInfo("QSQLITE","localhost","qt.db");
    sqlUtil->initDatabase();
    return a.exec();
}

2. 使用

//先获取数据库操作对象:SqlUtil::instance(),再操作里面封装好的方法,比如查询,插入,关闭数据库。
SqlUtil::instance()->executeSql(query);

三、增删查改例子

#include "mainwindow.h"
#include <QApplication>
#include <QString>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QDebug>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    //1.根据驱动获取数据库操作实例
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    //2.加载数据源
    db.setHostName("localhost");
    //如果没有这个数据库那么会创建,如果存在,那么不会创建
    db.setDatabaseName("qt_test.db");
    // 3. 连接数据库
    bool bl = db.open();
    if(!bl)
    {
        qDebug() << db.lastError().text();
    }
    else
    {
        //注意:这个连接成功不能作为正真连接成功数据的标准。如果能操作数据库才算连接成功
        qDebug() <<db.databaseName() <<"数据库连接成功了...";
    }

    QSqlQuery query;
    //创建表
    query.exec("create table addres(id int primary key, name varchar);");

    //插入
    query.prepare("INSERT INTO addres (id, name) "
                "VALUES (:id, :name)");
    query.bindValue(":id", 1002);
    query.bindValue(":name", "上海");
    query.exec();

    //查询
    query.exec("select id,name from addres");
    // 遍历结果集
    while(query.next())
    {
        // 从当前记录中取出各个字段的值
        qDebug() << query.value(0).toString()
                 << query.value(1).toString();
    }

    //修改
    query.prepare("update addres set name = :name where id = 1001");
    query.bindValue(":name", "广东");
    query.exec();

    //删除
    query.exec("delete from addres where id = 1002");

    //查询
    query.exec("select id,name from addres");

    qDebug() <<"----------";
    // 遍历结果集
    while(query.next())
    {
        // 从当前记录中取出各个字段的值
        qDebug() << query.value(0).toString()
                 << query.value(1).toString();
    }

    return a.exec();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT——操作数据库03 的相关文章

  • 将 ARGB 拆分为字节值

    我有一个 ARGB 值存储为 int 类型 它是通过调用 ToArgb 来存储的 我现在想要来自 int 值的各个颜色通道的字节值 例如 int mycolor 16744448 byte r g b a GetBytesFromColor
  • 如何转发声明要在 unique_ptr 的标准容器中使用的类

    在智能指针的标准容器中使用它时 是否可以避免完整的类定义可见 例如 我无法编译以下内容 include
  • 表达式访问者仅为某些 lambda 表达式调用 VisitParameter

    我希望能够使用嵌套扩展方法将 EF 中的实体投影到相应的视图模型 参见我之前的问题使用扩展方法在 EF 中投影单个实体 https stackoverflow com questions 39585427 projection of sin
  • OpenCV SVM 给出奇怪的预测结果

    我对 OpenCV 和支持向量机都很陌生 我想使用 SVM 训练具有两个标签的数据集 然后预测给定集合的标签 我当前的集合包含大约 600 行 具有相等的类分布 1 为 300 行 1 为 300 行 包含 34 列 这是我当前用于设置 O
  • 提取单花括号内的值

    我想要一个收藏 value 一个字符串使用正则表达式 例如 lorem ipsum field1 lorem ipsum field2 lorem ipsum field1 lorem ipsum field2 field3 我会得到 fi
  • 使用 LINQ 展平嵌套字典

    所以我有一本形式的字典Dictionary
  • 有没有办法找到dll公开的所有函数

    我一直在寻找一种方法来获取映射到 dll 中函数名称的所有字符串 我的意思是您可以调用 GetProcAddress 的所有字符串 如果你对 dll 进行十六进制转储 符号 字符串 就在那里 但我认为必须有一个系统调用来获取这些名称 如果您
  • 可以通过模板间接访问基类中的私有类型

    我试图在编译时根据类型是否在给定范围内公开可用来选择要使用的类型 最好直接看代码 include
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • 如何将输出重定向到 boost 日志?

    我有一个使用boost log的C 程序 我加载了用户提供的动态链接库 我想将 stderr 重定向到 boost 日志 以便用户的库随时执行以下操作 std cerr lt lt Some stuff 它产生相同的结果 BOOST LOG
  • 如何在 C 语言中获取输入中的空格

    我想从控制台获取字符数组 它还包含空格 我在 C 中知道的唯一方法是 scanf 但是一旦遇到空格 它就会停止接受输入 我该做什么 这就是我正在做的事情 char address 100 scanf s address 尝试使用 fgets
  • 我的代码哪里有泄漏?

    下面是我的代码 它打开一个 XML 文件 old xml 过滤无效字符并写入另一个 XML 文件 abc xml 最后 我将再次加载 XML abc xml 当执行以下行时 出现异常 表示 xml 文件被另一个进程使用 xDoc Load
  • 从 AuthorizeAttribute 继承的属性不起作用

    我目前正在尝试根据用户角色在新的 ASP MVC 5 应用程序中实现安全性 目标是防止用户在没有特定角色 或更高角色 的情况下访问某些控制器或控制器方法 根据到目前为止我所读到的问题 我创建了一个继承 AuthorizeAttribute
  • 如何解决 boost::multi precision::cpp_dec_float 除法错误

    除以boost multiprecision cpp dec float有某种舍入误差 如下 include
  • 如何在 stl 模板中使用导出类 (__declspec(dllexport))?

    我正在使用导出的类 class declspec dllexport myclass private template declspec dllexport class std map
  • 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

    有谁知道如何使用 DataGridViewCheckboxCell 禁用 DataGridView 中的复选框 我可以将其设置为只读 并设置背景颜色 但我无法让复选框本身显示为禁用状态 有什么想法吗 Guess 你必须自己画 http so
  • 如何使用 .NET 捕获我的桌面视频?

    我想知道是否有任何方法可以使用 NET 捕获我的桌面的视频 截屏视频 我并不是在寻找截屏软件 而只是在寻找一种可以让我自己生成桌面视频的技术 我想过拍摄多个屏幕截图 但我不确定如何以编程方式生成带有图像序列的视频 有人有主意吗 Thanks
  • 从数据库配置中的连接字符串中删除 SSIS 密码

    我有一个 SSIS 包 它使用 SQL 服务器中的 SSIS 配置表来检索 OLE DB 连接管理器的连接字符串属性 问题是我还需要相同的连接字符串来调用使用实体框架的程序集 我尝试访问连接管理器连接字符串属性 但 SSIS 总是删除密码
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en
  • 为什么 INT64_MIN 的定义不同?为什么他们的行为不同?

    The stdint h我公司的标题是 define INT64 MIN 9223372036854775808LL 但在我项目的一些代码中 一位程序员写道 undef INT64 MIN define INT64 MIN 92233720

随机推荐

  • 服务器系统手册,服务器安全使用手册

    系统安全 1 保存好系统密码并定期进行修改 2 开启系统自动更新功能 3 开启杀毒软件 经常更新病毒库 定期扫描病毒 4 做好网站的注入漏洞检查 做好网站目录访问权限控制 5 慎重安装硬件驱动 以免损坏操作系统 6 不要安装路由和远程访问服
  • 傅里叶分析之掐死教程

    作者 韩昊 知乎 Heinrich 微博 花生油工人 知乎专栏 与时间无关的故事 谨以此文献给大连海事大学的吴楠老师 柳晓鸣老师 王新年老师以及张晶泊老师 转载的同学请保留上面这句话 谢谢 如果还能保留文章来源就更感激不尽了 更新于 201
  • python创建虚拟环境报错_centos8使用python3自带的venv创建虚拟环境报错问题

    一 背景 damon localhost python3 m venv pdf env Error Command home damon pdf env bin python3 Im ensurepip upgrade default pi
  • IPsec协议过程

    版权声明 如有需要 可供转载 但请注明出处 https blog csdn net City of skey article details 86618784 目录 1 ipsec协议简介 2 IPSec工作模式 2 1 传输模式 2 2
  • 三星S5P6818之UBOOT网络配置

    三星S5P6818之UBOOT网络配置 使用友善提供的固件烧写到SD卡发现UBOOT并不能联网 于是研究了UBOOT源码 并调通了网络 以下步骤亲测可用 前言 这个适合友善nanopi3系列的开发板 M3 Fire3 T3等 或者其他使用
  • Python不平衡数据处理库imblearn安装和使用

    一般直接pip安装即可 安装不成功可能是因为 没有安装imblearn需要的Python模块 对应安装即可 pip install U imbalanced learn imblearn中的过采样方法 Over sampling metho
  • VMware 安装、移除Ubuntu系统

    目录 前言 安装虚拟机 1 新建虚拟机 2 进入向导 3 选择系统镜像 4 添加系统设置 用户名主机名密码 lt 实际没啥用 在系统安装过程中才设置的 gt 5 设置虚拟机名称 存放位置 6 磁盘容量 7 设置虚拟机硬件配置 8 自定义硬件
  • vue框架

    一 vue是什么 官方解释 vue是一套用于构建用户界面的渐进式框架 vue是一个js框架 提供了一套开发规则 按照这个开发规则可提高开发效率 补充 渐进式意思是 vue js本身功能局限 一旦配合其他的工具可以增强其能力 vue rout
  • Linux离线安装NTP服务,无外网环境下配置本地时间同步

    1 常用命令 rpm qa grep ntp 查询已安装的ntp版本信息等 rpm e nodeps ntp 4 2 6p5 29 el7 centos 2 x86 64 卸载 systemctl status ntpd 查询ntp服务状态
  • es打分机制

    基于Lucene的倒排索引算法
  • 【python数据挖掘课程】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取

    这是 Python数据挖掘课程 系列文章 也是我这学期上课的部分内容及书籍的一个案例 本文主要讲述KNN最近邻分类算法 简单实现分析平衡秤数据集 希望这篇文章对大家有所帮助 同时提供些思路 内容包括 1 KNN算法基础原理知识 2 最近邻分
  • 如何手动运行一个容器【一】

    作者 行云创新 周朋 每个刚涉足容器的人都会对容器的实现有所困惑 容器是如何实现的 是如何复用宿主机的资源 并且实现资源隔离的 下面会用shell创建一个容器 为大家展示一个容器的创建过程 1 创建镜像 我们一般用 docker pull
  • 宏定义的#和##

    宏定义中一个 表示右侧的符号转化为字符串 比如 define STR x x QString s STR 3 编译ok s值为 3 之前在看QT源码时 发现了下面的宏定义 define QLOCATION 0 FILE QT STRINGI
  • Typora + Gitee 配置图床_图片自动上传教程

    一 创建 Gitee 仓库 进入 Gitee 官网 注册一个属于自己的账号 点击创建仓库并且设置为开源 一定要是开源的public 只有这样你的图片才能被别人访问到 二 设置私人令牌 进入个人设置 gt 选择私人令牌进行创建 gt 设置自己
  • 华为od机考真题-HJ6-质数因子(简单)

    while 1 try num int input c 2 while c lt num 0 5 if num c 0 print c end
  • C++ Primer 学习笔记十五 —— 面向对象编程

    记录笔记原则 1 用简单易懂的语言叙述自己的理解 避免照搬原文 2 用实例说明 避免空洞 3 多做总结和横向对比 避免片面 面向对象三个基本概念 抽象 继承 动态绑定 继承使我们简化了类的定义 动态绑定使我们简化了接口的实现 使得所有继承层
  • 探究java IO之AutoCloseable,Closeable和Flushable接口

    http blog csdn net caiwenfeng for 23 article details 41862225 有3个接口对于流类相当重要 其中两个接口是Closeable和Flushable 它们是在java io包中定义的
  • BQ40Z50/BQ4050/BQ40Z80 等 BQ40xxx 系列电量计外围电路设计指导

    TI 电量计在消费和工业市场电池产品广泛应用 本文围绕电量计的功能逐一介绍电量计供电和 采样 对外交互 电池保护 电池均衡等外围电路设计 以帮助大家优化电量计电路设计 提高 开发效率 FAE 壹伍柒 陆陆贰陆 柒捌贰伍 1 电量计外围电路框
  • GPIO 8种工作模式

    GPIO 是什么 GPIO全称General Purpose Input Output 即通用输入 输出 其实GPIO的本质就是芯片的一个引脚 通常在ARM中所有的I O都是通用的 不过由于每个开发板上都会设计不同的外围电路 这就造成GPI
  • QT——操作数据库03

    目录标题 一 安装数据库 二 连接数据库 一 在项目的pro文件中增加一行代码 二 连接sqlite 三 封装连接数据库操作 三 增删查改例子 一 安装数据库 一般使用mysql或者sqlite mysql安装教程 sqlite安装教程 1