官方网站下载安装云支付,百度搜索网站介绍,微网站建设报价方案,游戏排行榜20230#xff1a;前言
#x1faa7; 什么情况需要数据库?
1 大规模的数据需要处理#xff08;比如上千上万的数据量#xff09;2 需要把数据信息存储起来#xff0c;无论是本地还是服务上#xff0c;而不是断电后数据信息就消失了。
如果不是上面的原因化#xff0c;一般…0前言 什么情况需要数据库?
1 大规模的数据需要处理比如上千上万的数据量2 需要把数据信息存储起来无论是本地还是服务上而不是断电后数据信息就消失了。
如果不是上面的原因化一般可以使用数组来处理。 一般常使用的数据库驱动是MYSQL和QSQLITE。二者区别在于前者用于服务器存储信息后者用于本地存储信息。并且QSQLITE主要用于嵌入式占用资源非常低占用内存小通常几百k就搞定。’ 这里博主因为对MySQL熟悉一些就使用MySQL来进行数据库的连接 一、Mysql的安装
因为我们项目的方案是程序的运行以及相关数据的存储都在一台主机上所以不论打不打包。首先要在主机上安装Mysql的。Mysql的安装教程我参考的是这个MySQL安装和配置教程超详细版本
安装好后利用命令行或其他工具在MySQL中创建一个存储项目数据的数据库方便之后使用QT用代码对数据库进行连接、建表和增删改查的操作
Winr打开cmd输入命令“mysql -u root -p”按下回车键输入MySQL密码按下回车键创建数据库
create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则];注意不要忘记末尾的分号 二、通过ODBC连接MySQL数据库
官方解释: ODBCOpen Database Connectivity开放数据库互连提供了一种标准的API应用程序编程接口方法来访问数据库管理系统DBMS。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持用户可以直接将SQL语句送给ODBC。ODBC的设计者们努力使它具有最大的独立性和开放性与具体的编程语言无关与具体的数据库系统无关与具体的操作系统无关。 简单的说就是我的qt中含有ODBC的驱动 所以利用ODBC去使用MySQL的数据库
2.1下载ODBC
官网 选择和qt编译器相同的字节比如我的qt使用的是64字节的 下载完成后点卡下载下来的.msi文件并运行 下载一直点击next
选择custom,表示自定义安装以便修改安装位置 最后一直点击next然后再install即可等待安装好后即可。
安装好之后关闭窗口搜索ODBC,并运行程序
2.2使用ODBC连接MySQL数据库
添加MySQL的DSN 红色的可以随便填,是自己对于ODBC驱动的描述,粉色的是MySQL的用户名和密码,数据库选择你在MySQL中创建的数据库名字即可
点击Test测试是否能够成功连接如果出现下图说明连接成功 然后点击应用和确定进行添加
2.3qt通过ODBC连接MySQL
现在main.cpp中加入下面代码测试一下能不能在qt中连接成功
QSqlDatabase db QSqlDatabase::addDatabase(QODBC);db.setHostName(127.0.0.1);db.setPort(3306);db.setDatabaseName(是你在ODBC中创建的Data source );db.setUserName(用户名);db.setPassword(密码);bool ok db.open();if (ok){QMessageBox::information(this, infor, success);}else {QMessageBox::information(this, infor, open failed);qDebug()error open database becausedb.lastError().text();}
Tips:这里可能会报错VS2019 C1083 无法打开包括文件: “QSqlDatabase”
是vs里面项目配置的问题。 看到这个错误应该是没有dll然后sql很容易想到数据库所以在qt模块里添加比较方便。
不出意外运行程序可以成功连接 之后在主机进行安装时除了打包程序应该还需要安装对应的Mysql和ODBC 2.4qt通过ODBC操作数据库
连接上数据库一般就是使用数据库进行对数据库的增删改查。 这里有三种方法。 首先单独建立一个头文件来处理数据库连接如建立头文件connection.h:
#ifndef CONNECTION_H
#define CONNECTION_H#include QMessageBox
#include QSqlDatabase
#include QSqlQuery
#include QDebugstatic bool createConnection(){//连接第一个数据库//QMYSQLQSqlDatabase db QSqlDatabase::addDatabase(QMYSQL, connection1);//需要使用的数据库驱动和联检建立的名称方便建立多个数据库连接【使用不同的数据库时】区分db.setHostName(127.0.0.1);//连接地址db.setUserName(root);//数据库账户db.setPassword(root);//密码db.setPort(8889);//端口//test_majiang.dbdb.setDatabaseName(test_majiang);//需要用到的数据库if (!db.open()) {//如果数据库连接失败则弹出//critical(QWidget *parent, const QString title,//const QString text,//QMessageBox::StandardButtons buttons Ok,//QMessageBox::StandardButton defaultButton NoButton)QMessageBox::critical(0, Cannot open database,Unable to establish a database connection, QMessageBox::Cancel);return false;}return true;
}#endif // CONNECTION_H如果需要移除一个数据库连接可以使用: QSqlDatabase::close();//关闭数据库QSqlDatabase::removeDatabase();//移除该连接2.4.1使用QSqlQuery
头文件
#include connection.h
#include QVariant
#include QSqlDriver
#include QSqlRecord
#include QSqlField
#include QSqlError使用数据库前的准备 //创建数据库连接if(!createConnection()) return 1;//返回情况可以替换视不同情况而定//指定某个数据库连接QSqlDatabase db2 QSqlDatabase::database(connection1);开始对数据进行操作 首先创建QSqlQuery 对象然后进行操作。 QSqlDatabase db2 QSqlDatabase::database(connection2);QSqlQuery query2(db2);进行创表和插入值 // qDebug() connection2:;//创建表并插入值query2.exec(create table student (id int primary key,name varchar(20)));query2.exec(insert into student values(0, Mike));query2.exec(insert into student values(1, Lili));query2.exec(insert into student values(2, Jame));批量处理 上面的单条插入语句明显比较麻烦可以使用批量插入数据 query2.exec(insert into student(id,name) values(3,Qinsong));//单挑操作//名称绑定query2.prepare(insert into student(id, name) values(:id, :name));int idValue 4;QString nameValue Songjiang;query2.bindValue(:id, idValue);//绑定数据query2.bindValue(:name, nameValue);query2.exec();//执行//位置绑定query2.prepare(insert into student(id, name) values(?, ?));int idValue2 5;QString nameValue2 LingChong;query2.addBindValue(idValue2);//绑定数据query2.addBindValue(nameValue2);if(!query2.execBatch()) qDebug() 位置绑定 query2.lastError() endl;//如果执行不成功执行//批量处理query2.prepare(insert into student(id, name) values(?,?));QVariantList ids;ids 6 7 8;query2.addBindValue(ids);QVariantList names;names Qinghua Nanda Zhongkeda;query2.addBindValue(names);if(!query2.execBatch()) qDebug() query2.lastError() endl; 进行查询并输出查询结果 query2.exec(select * from student);//执行sql语句while(query2.next()){qDebug() query2.value(0).toInt() query2.value(1).toString();}查看数据驱动支持特性 查看当前数据库是否是支持某特性比如当前记录的索引数即结果条数 int numRows;if(db2.driver()-hasFeature(QSqlDriver::QuerySize)){//是否该特性qDebug() has feature:query size;numRows query2.size();}else{qDebug() no feature:query size;query2.last();numRows query2.at() 1;//使用at需要之前使用quey2.next()遍历所有select搜索后的结果,而使用query2.size()则不需要}//此处执行上面的查询操作下面的操作才有意义qDebug() row number: numRows;//指向索引为1的记录即第二条记录query2.seek(1);//返回当前索引值qDebug() current index: query2.at();//获得当前行的记录QSqlRecord record query2.record();//获得记录中id和name两个字段的值int id record.value(id).toInt();QString name record.value(name).toString();qDebug() id id name: name;//获得索引为1的字段即第二个字段QSqlField field record.field(1);//输出字段名和字段值结果为name和MaLiangqDebug() second field: field.name() field value: field.value().toString();
事务使数据操作变为原子性 如果中间有一步sql操作执行出错则全部sql操作都不执行。 QSqlDatabase db2 QSqlDatabase::database(connection2);QSqlDatabase::database().transaction();//开始类似于mutex线程锁QSqlQuery query(db2);//此语句必须在上面一条语句的后面//执行sql操作QSqlDatabase::database().commit();//结束2.4.2使用QSqlQueryModel查询模型
优势
这是基于sql查询的只读模型编写sql语句变得容易。
文件头
#include QSqlQueryModel核心代码 QSqlDatabase db QSqlDatabase::database(connection1);QSqlQueryModel *model new QSqlQueryModel(this);model-setQuery(select * from student, db);model-setHeaderData(0, Qt::Horizontal, tr(学号));model-setHeaderData(1, Qt::Horizontal, tr(姓名));model-setHeaderData(2, Qt::Horizontal, tr(课程));QTableView *view new QTableView(this);view-setModel(model);setCentralWidget(view);2.4.3使用QSqlTableModel表格模型⭐
先上结果
优势 编译的代码很容易适应其他的数据源例如后面如果要使用xml文件来存储数据只需要更换数据模型。 提供了一次只能操作一个sql表的读/写模型可以浏览和修改独立的sql表并且只需编写很少的代码无需了解sql语句。 1 准备 头文件
#include QSqlTableModelQSqlTableModel* model;//创建对象指针2 进行操作 QSqlDatabase db QSqlDatabase::database(connection1);model new QSqlTableModel(this, db);//由于在窗口的类中创建对象因此实例化对象时使用this指针指向操作函数的指针作为父对象model-setTable(student);model-select();//执行//设置编辑策略model-setEditStrategy(QSqlTableModel::OnManualSubmit);//对所有模型改变立即用到数据库ui-tableView-setModel(model);UI设计 对应槽函数
// 提交修改按钮
void MainWindow::on_pushButton_clicked()
{// 开始事务操作model-database().transaction();if (model-submitAll()) {if(model-database().commit()) // 提交QMessageBox::information(this, tr(tableModel),tr(数据修改成功));} else {model-database().rollback(); // 回滚QMessageBox::warning(this, tr(tableModel),tr(数据库错误: %1).arg(model-lastError().text()),QMessageBox::Ok);}
}// 撤销修改按钮
void MainWindow::on_pushButton_2_clicked()
{model-revertAll();
}// 查询按钮进行筛选
void MainWindow::on_pushButton_5_clicked()
{QString name ui-lineEdit-text();// 根据姓名进行筛选一定要使用单引号model-setFilter(QString(name %1).arg(name));model-select();
}// 显示全表按钮
void MainWindow::on_pushButton_6_clicked()
{model-setTable(student);model-select();
}// 按id升序排列按钮
void MainWindow::on_pushButton_7_clicked()
{//id字段即第0列升序排列model-setSort(0, Qt::AscendingOrder);model-select();}// 按id降序排列按钮
void MainWindow::on_pushButton_8_clicked()
{model-setSort(0, Qt::DescendingOrder);model-select();}
// 删除选中行按钮
void MainWindow::on_pushButton_4_clicked()
{// 获取选中的行int curRow ui-tableView-currentIndex().row();// 删除该行model-removeRow(curRow);int ok QMessageBox::warning(this,tr(删除当前行!),tr(你确定删除当前行吗), QMessageBox::Yes, QMessageBox::No);if(ok QMessageBox::No){ // 如果不删除则撤销model-revertAll();} else { // 否则提交在数据库中删除该行model-submitAll();}}
// 添加记录按钮
void MainWindow::on_pushButton_3_clicked()
{// 获得表的行数int rowNum model-rowCount();int id 10;// 添加一行model-insertRow(rowNum);model-setData(model-index(rowNum, 0), id);// 可以直接提交//model-submitAll();
}
三、项目实战
connection.h是负责连接数据库和创建表的头文件
#ifndef CONNECTION_H
#define CONNECTION_H#include QMessageBox
#include QSqlDatabase
#include QSqlQuery
#include QDebug
#pragma execution_character_set(utf-8); static bool createConnection() {//连接第一个数据库//QMYSQLQSqlDatabase db QSqlDatabase::addDatabase(QODBC, connection1);//需要使用的数据库驱动和联检建立的名称方便建立多个数据库连接【使用不同的数据库时】区分db.setHostName(127.0.0.1);//连接地址db.setUserName(root);//数据库账户db.setPassword(55667788);//密码db.setPort(3306);//端口//test.dbdb.setDatabaseName(test);//需要用到的数据库if (!db.open()) {//如果数据库连接失败则弹出//critical(QWidget *parent, const QString title,//const QString text,//QMessageBox::StandardButtons buttons Ok,//QMessageBox::StandardButton defaultButton NoButton)QMessageBox::critical(0, Cannot open database,Unable to establish a database connection, QMessageBox::Cancel);return false;}else {QMessageBox::information(NULL, infor, link success);}//下面来创建表//如果MySQL数据库中已经存在同名的表则下面代码不会执行QSqlQuery query2(db);// qDebug() connection2:;
//创建表并插入值query2.exec(create table student (id int primary key,name varchar(20)));query2.exec(insert into student values(0, Mike));query2.exec(insert into student values(1, Lili));query2.exec(insert into student values(2, Jame));}#endif // CONNECTION_HAdmin是操作数据库的管理界面 Admin.h:
#pragma once#include QMainWindow
#include ui_Admin.h
#include QSqlTableModel
#pragma execution_character_set(utf-8); class Admin : public QMainWindow
{Q_OBJECTpublic:Admin(QWidget *parent nullptr);~Admin();QSqlTableModel* model;//创建对象指针private:Ui::AdminClass ui;private slots:void on_add_clicked();void on_modify_clicked();void on_del_clicked();void on_rollback_clicked();void on_show_all_clicked();
};
Admin.cpp:
#include Admin.h
#include qmessagebox.h
#include QSqlDatabase
#include QMessageBox
#include qsqlerror.h
#include connection.h
#include QSqlTableModelAdmin::Admin(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);if (!createConnection()) {return;}QSqlDatabase db QSqlDatabase::database(connection1);model new QSqlTableModel(this, db);//由于在窗口的类中创建对象因此实例化对象时使用this指针指向操作函数的指针作为父对象model-setTable(student);model-select();//执行QTableView* view new QTableView;view-setModel(model);// 你可以根据你数据库表的实际列名进行设置QHeaderView* header view-horizontalHeader();header-setModel(model);header-setSectionResizeMode(QHeaderView::Stretch);// 设置显示名称从0开始计数model-setHeaderData(0, Qt::Horizontal, tr(列名1));model-setHeaderData(1, Qt::Horizontal, tr(列名2));model-setHeaderData(2, Qt::Horizontal, tr(列名3));//设置编辑策略model-setEditStrategy(QSqlTableModel::OnManualSubmit);//对所有模型改变立即用到数据库ui.tableView-setModel(model);}Admin::~Admin()
{}// 添加记录按钮
void Admin::on_add_clicked()
{// 获得表的行数int rowNum model-rowCount();int id 10;// 添加一行model-insertRow(rowNum);model-setData(model-index(rowNum, 0), id);// 可以直接提交//model-submitAll();
}// 删除选中行按钮
void Admin::on_del_clicked()
{// 获取选中的行int curRow ui.tableView-currentIndex().row();// 删除该行model-removeRow(curRow);int ok QMessageBox::warning(this, tr(删除当前行!),tr(你确定删除当前行吗), QMessageBox::Yes, QMessageBox::No);if (ok QMessageBox::No){ // 如果不删除则撤销model-revertAll();}else { // 否则提交在数据库中删除该行model-submitAll();}}
// 撤销修改按钮
void Admin::on_rollback_clicked()
{model-revertAll();
}// 提交修改按钮
void Admin::on_modify_clicked()
{// 开始事务操作model-database().transaction();if (model-submitAll()) {if (model-database().commit()) // 提交QMessageBox::information(this, tr(tableModel),tr(数据修改成功));}else {model-database().rollback(); // 回滚QMessageBox::warning(this, tr(tableModel),tr(数据库错误: %1).arg(model-lastError().text()),QMessageBox::Ok);}
}
// 显示全表按钮
void Admin::on_show_all_clicked() {model-setTable(student);model-select();
}
功能正常