QT实现连接数据库以及查询等操作
目录
- 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() | void | int | 设置数据库连接的端口号 |
QSqlDatabase :: setHostName() | void | QString | 设置数据库连接的主机名 |
QSqlDatabase ::setPassword() | void | QString | 设置数据库连接的密码 |
QSqlDatabase ::setUserName() | void | QString | 设置数据库连接的用户名 |
QSqlDatabase ::setDatabaseName() | void | QString | 设置数据库连接的数据库名 |
QTableWidget::clear() | void | 无 | 清除QTableWidget中的所有表项 |
QVector::clear() | void | 无 | 清除QVector中的所有元素 |
QSqlQuery::prepare() | bool | QString | 准备SQL查询语句 |
QSqlQuery::exec() | bool | 无 | 执行SQL查询或执行上次准备的查询语句 |
QSqlQuery::exec(bool) | bool | QString | 执行SQL查询语句,并将结果存储于内存以供后续访问 |
QSqlQuery::size() | int | 无 | 获取查询结果的记录数 |
QSqlQuery::bindValue() | void | QString, QVariant | 将参数绑定到SQL查询语句中的占位符 |
QRecord::count() | int | 无 | 返回QRecord中的字段数 |
QRecord::value() | QVariant | int | 获取指定字段的值 |
源代码
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来连接数据库。