QT实现连接MySQL数据库以及查询等操作

QT实现连接数据库以及查询等操作

实现效果

在这里插入图片描述
功能包含数据库的增删改查和界面的显示,因为没有用.ui文件所以控件的位置都是手动设置的,写的有点费劲

建立数据库

首先打开Navicat,新建一个名字为bak_db的数据库,然后新建查询导入下面的sql语句:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `permission` int(2) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, 'admin', '123456', 1);
INSERT INTO `users` VALUES (32, 'xfgc', 'dfhgrj', 2);
INSERT INTO `users` VALUES (39, '123', '456', 1);

SET FOREIGN_KEY_CHECKS = 1;

然后刷新显示表已经创建好了,接下来就开始进行操作了:

代码实现

文件结构

在这里插入图片描述
源码在我的github上,感兴趣的话可以下载运行试一下欢迎fork和star
运行不成功的可能是MySQL数据库的动态库没有导入,可以看一下这篇文章

连接数据库

首先是使用QSqlDatabase来创建数据库对象,使用

QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");

后设置端口号、数据库地址、用户名、密码、数据库名

    db.setPort(3306);
    db.setHostName(hostname);//localhost
    db.setPassword(sqlpasswd);//数据库密码
    db.setUserName(sqlname);//数据库登录名
    db.setDatabaseName(dbname);//数据库的名字 我用的上面的数据库为bak_db

执行项目中的conn()函数就可以发现数据库连接成功了
关于从数据库中读取出来的信息,数据先存在二维数组中,后遍历二维数组放到QTableWidget中

void Mysql::flush_data(QVector<QVector<QString>>&userinfo)
{
    table->clear();
    if(!userinfo.size())return;
    table->setRowCount(userinfo.size());
    table->setColumnCount(4);
    for(int i=0;i<userinfo.size();i++)
    {
        for(int j=0;j<userinfo[0].size();j++)
        {
            table->setItem(i,j,new QTableWidgetItem(userinfo[i][j]));
        }
    }
     table->setHorizontalHeaderLabels({"id","用户名","密码","权限"});
}

bool Mysql::adduserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("insert into users(username,password,permission) values(:user,:passwd,:per);");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按姓名删除


bool Mysql::del_byname(QString name)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  username=:user;");
    query.bindValue(":user",name);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按权限删除

bool Mysql::del_bypermission(QString permissionn)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  permission=:permission");
    query.bindValue(":permission",permissionn);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按名字查询

bool Mysql::updateuserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("UPDATE users SET username=:user, password=:passwd ,permission=:per WHERE  username=:user;");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}


查询表中所有数据

void Mysql::findall()
{
    userinfo.clear();
    QSqlQuery query(db);
    query.prepare("select * from users;");
    if(query.exec())
    {
         while (query.next()) {
             QVector<QString>rec;
             for(int i=0;i<query.record().count();i++)
             {
                 rec.push_back(query.record().value(i).toString());
             }
             userinfo.push_back(rec);
         }
    }
}

按名字查询

bool Mysql::find_byname(QString name)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where username=:name;");
        query.bindValue(":name",name);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());

                 userinfo.push_back(rec);
             }
             return true;
        }
            return false;
}

按权限查询

bool Mysql::find_bypermission(QString permissionn)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where permission=:permission;");
        query.bindValue(":permission",permissionn);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());
                 userinfo.push_back(rec);
             }
             return true;
        }
        return false;
}

所用类及其函数解释

所用的类:

类名作用解释
QSqlDatabase用于管理和操作数据库连接的类QSqlDatabase类提供了与数据库建立连接、执行查询和事务处理相关的功能。
QTableWidget用于显示和编辑二维表格数据的控件QTableWidget类是Qt中用于展示和编辑二维表格数据的控件,允许用户直接在表格中进行修改、选择和排序。
QVector动态数组容器类,用于存储任意类型的数据QVector类是Qt中的一个动态数组容器,可以存储和操作各种类型的数据,支持自动内存管理和高效的插入、删除操作。
QSqlQuery用于执行SQL查询语句并处理结果的类QSqlQuery类提供了执行SQL查询语句、处理结果集以及绑定参数等功能,可以方便地进行数据库的查询和数据操作。
QRecord代表数据库结果集中的一行数据的类QRecord类用于代表数据库查询结果集中的一行数据,可以通过字段名或索引来访问和操作每个字段的值。

在项目中用到的函数的解释:

函数名返回值参数作用
QSqlDatabase ::setPort()voidint设置数据库连接的端口号
QSqlDatabase :: setHostName()voidQString设置数据库连接的主机名
QSqlDatabase ::setPassword()voidQString设置数据库连接的密码
QSqlDatabase ::setUserName()voidQString设置数据库连接的用户名
QSqlDatabase ::setDatabaseName()voidQString设置数据库连接的数据库名
QTableWidget::clear()void清除QTableWidget中的所有表项
QVector::clear()void清除QVector中的所有元素
QSqlQuery::prepare()boolQString准备SQL查询语句
QSqlQuery::exec()bool执行SQL查询或执行上次准备的查询语句
QSqlQuery::exec(bool)boolQString执行SQL查询语句,并将结果存储于内存以供后续访问
QSqlQuery::size()int获取查询结果的记录数
QSqlQuery::bindValue()voidQString, QVariant将参数绑定到SQL查询语句中的占位符
QRecord::count()int返回QRecord中的字段数
QRecord::value()QVariantint获取指定字段的值

源代码

mysql.pro

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mysql.cpp

HEADERS += \
    mysql.h

FORMS +=

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

mysql.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QWidget>
#include<QSql>
#include<QSqlDatabase>
#include<QDebug>
#include<QSqlQuery>
#include<QSqlRecord>
#include <QSettings>
#include <QTableWidget>
#include <QPushButton>
#include <QLineEdit>
#include<QMessageBox>
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE

class Mysql : public QWidget
{
    Q_OBJECT
public:
    Mysql(QWidget *parent = nullptr);
    ~Mysql();
    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
    QString sqlname,hostname,sqlpasswd,dbname,sqlport;
    //查
    QPushButton* findname;
    QPushButton* findpermission;
    QLineEdit* inputinfo;
    //增
    QPushButton* addinfo;
    QLineEdit* user,*passwd,*permission;
    //改
    QPushButton* updateinfo;
    //删
    QPushButton* delname;
    QPushButton* delpermission;
    QLineEdit* inputdelinfo;
    QVector<QVector<QString>>userinfo;
    QTableWidget* table;
    QPushButton* all;
    //建立连接
    void conn();
    void init();
    //登录
    bool isAdmin;//判断是否是管理员
    bool isuser(QString username,QString password);
    void findall();//查看所有用户
    void flush_data(QVector<QVector<QString>>&userinfo);
    bool find_byname(QString name);
    bool find_bypermission(QString permission);
    bool adduserinfo(QString user,QString passwd,QString per);
    bool updateuserinfo(QString user,QString passwd,QString per);
    bool del_byname(QString name);
    bool del_bypermission(QString permissionn);
private:
};

#endif // MAINWINDOW_H

mysql.cpp

#include "mysql.h"

Mysql::Mysql(QWidget *parent)
    : QWidget(parent)
{
    conn();
    init();
}

Mysql::~Mysql()
{}

void Mysql::conn()
{
    sqlname="root";
    sqlpasswd="123456";
    hostname="localhost";
    dbname="bak_db";
    db.setPort(3306);
    db.setHostName(hostname);
    db.setPassword(sqlpasswd);
    db.setUserName(sqlname);
    db.setDatabaseName(dbname);
    if(db.open())
    {
        qDebug()<<"success!";
    }
    else {qDebug()<<"failed!";}
   // db.close();
}

void Mysql::init()
{
    this->setFixedSize(1000,1000);
    table=new QTableWidget(this);
    table->move(20,200);
    table->setFixedSize(500,500);
    QStringList headers;
    headers << "id" << "用户名" << "密码"<<"权限";
    table->setColumnCount(4);
    table->setHorizontalHeaderLabels(headers);

    inputinfo=new QLineEdit(this);
    inputinfo->setPlaceholderText("请输入姓名 / 权限");
    inputinfo->move(20,50);

    findname=new QPushButton("按姓名查询",this);
    findname->move(180,30);
    connect(findname,&QPushButton::clicked,[this](){
        QString name=inputinfo->text();
        if(find_byname(name))
        {
            flush_data(userinfo);
            userinfo.clear();
        }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
    });

     findpermission=new QPushButton("按权限查询",this);
     findpermission->move(180,70);
     connect(findpermission,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(find_bypermission(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }
        else QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     inputdelinfo=new QLineEdit(this);
     inputdelinfo->setPlaceholderText("请输入姓名 / 权限");
     inputdelinfo->move(280,50);

     delname=new QPushButton("按姓名删除",this);
     delname->move(440,30);
     connect(delname,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(del_byname(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     delpermission=new QPushButton("按权限删除",this);
     delpermission->move(440,70);
     connect(delpermission,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(del_bypermission(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     addinfo=new QPushButton("添加信息",this);
     addinfo->move(440,100);
     connect(addinfo,&QPushButton::clicked,[this](){
         if(adduserinfo(user->text(),passwd->text(),permission->text()))
         {
             flush_data(userinfo);
         }
     });

     updateinfo=new QPushButton("修改信息",this);
     updateinfo->move(440,130);
     connect(updateinfo,&QPushButton::clicked,[this](){
         if(updateuserinfo(user->text(),passwd->text(),permission->text()))
         {
             flush_data(userinfo);
         }
     });
     
     user=new QLineEdit(this);
     user->move(20,120);
     user->setPlaceholderText("请输入用户名");

     passwd=new QLineEdit(this);
     passwd->move(160,120);
     passwd->setPlaceholderText("请输入密码");

     permission=new QLineEdit(this);
     permission->move(300,120);
     permission->setPlaceholderText("请输入权限(1/2)");

     all=new QPushButton("查看所有信息",this);
     all->move(20,160);
     connect(all,&QPushButton::clicked,[this](){
         findall();
         flush_data(userinfo);
     });
    findall();
    flush_data(userinfo);
}

bool Mysql::isuser(QString username, QString password)
{
    QSqlQuery query1(db),query2(db);
    query1.prepare("select * from  users where username=:username "
                   "and password=:password and permission=1;");//查询是否为管理员
    query1.bindValue(":username",username);
    query1.bindValue(":password",password);

    query2.prepare("select * from  users where username=:username,"
                  "and password=:password and permission=2;");//查询是否为普通职员
    query2.bindValue(":username",username);
    query2.bindValue(":password",password);

    if (query1.exec()) {
        isAdmin=true;
        qDebug()<<"管理员登陆成功";
        return true;
    }
    else if(query2.exec())
    {
        isAdmin=false;
        qDebug()<<"普通职员登陆成功";
        return true;
    }
    else
     {
        qDebug()<<"用户名或密码错误!";
    }
    return false;
}

void Mysql::flush_data(QVector<QVector<QString>>&userinfo)
{
    table->clear();
    if(!userinfo.size())return;
    table->setRowCount(userinfo.size());
    table->setColumnCount(4);
    for(int i=0;i<userinfo.size();i++)
    {
        for(int j=0;j<userinfo[0].size();j++)
        {
            table->setItem(i,j,new QTableWidgetItem(userinfo[i][j]));
        }
    }
     table->setHorizontalHeaderLabels({"id","用户名","密码","权限"});
}

void Mysql::findall()
{
    userinfo.clear();
    QSqlQuery query(db);
    query.prepare("select * from users;");
    if(query.exec())
    {
         while (query.next()) {
             QVector<QString>rec;
             for(int i=0;i<query.record().count();i++)
             {
                 rec.push_back(query.record().value(i).toString());
             }
             userinfo.push_back(rec);
         }
    }
}

bool Mysql::find_byname(QString name)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where username=:name;");
        query.bindValue(":name",name);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());

                 userinfo.push_back(rec);
             }
             return true;
        }
            return false;
}

bool Mysql::find_bypermission(QString permissionn)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where permission=:permission;");
        query.bindValue(":permission",permissionn);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());
                 userinfo.push_back(rec);
             }
             return true;
        }
        return false;
}

bool Mysql::adduserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("insert into users(username,password,permission) values(:user,:passwd,:per);");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::updateuserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("UPDATE users SET username=:user, password=:passwd ,permission=:per WHERE  username=:user;");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::del_byname(QString name)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  username=:user;");
    query.bindValue(":user",name);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::del_bypermission(QString permissionn)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  permission=:permission");
    query.bindValue(":permission",permissionn);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

main.cpp

#include "mysql.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Mysql w;
    w.show();
    return a.exec();
}

后面的话

写的时候发现每个表都需要使用数据类型(一维数组、哈希表、二维数组等)进行存储,而且基本上每涉及一个表就需要单独对这个表写增删改查之类的函数,这样造成了非常大的代码冗余,非常臃肿,但是目前我还没有想到什么办法能减少这种冗余简化代码,有一种方法是把数据库中的表对应的在qt中建立数据类,在类中建立对应表中表项的数据类型,之后查询到的数据对应的放到相应的类中,但是这样只是结构清晰了很多但是使用的内存空间还是同样大甚至更多。
其实也是因为自己这个月初要实现关于数据库的相关操作,然后就研究了一下,写完之后心血来潮想整理一下qt关于数据库的操作。感觉qt配置连接数据库简直比visualstudio简单太多了,甚至至今我还不能在vs上成功连接数据库,只能在vscode中使用cmakelists来连接数据库。

  • 7
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值