Qt5.14.2 无所不能的Qt数据库操作之旅

2024-03-29 01:36

本文主要是介绍Qt5.14.2 无所不能的Qt数据库操作之旅,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


身为程序员,数据库无疑是我们最为亲密无间的好伙伴。但如何高效地操作数据库,却一直是一个令人颇感棘手的难题。不过,没关系,我们的Qt大神们早已为此开辟出一条华丽绝伦的大道,就让我带你一览他们的绝世数据库操作艺术吧!


一、查询驱动,方能驱车万里


在对数据库开展操作之前,我们首先需要明确该使用何种驱动程序。而对于Qt大神来说,这个问题轻而易举:

QStringList drivers = QSqlDatabase::drivers();
foreach(QString driver, drivers)qDebug() << driver;

QSqlDatabase::drivers()这个静态方法会为我们列出Qt当前支持的所有SQL数据库驱动,包括:

QSQLITE
QMYSQL
QMYSQL3
QPSQL
QPSQL7
QOCI 
QTDS
QODBC
QODBC3
QIBASE
QDB2

要启用某个驱动,只需在构建Qt时将其编译进来即可。比如在Windows下启用ODBC驱动:

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

ODBC(Open Database Connectivity)是Microsoft推出的数据库连接标准,Qt通过QODBC驱动就能支持任何ODBC兼容的数据库,包括Access、SQL Server、Oracle等等。

接下来,让我们使用Qt连接并操作一个Access数据库,一睹Qt数据库艺术的绝世风采!


二、马到成功,QODBC唱主角


连接Access数据库的第一步,就是设置正确的数据源名称(DSN):

db.setDatabaseName("Driver={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};DBQ=C:/myDatabase.accdb");
if(db.open())
{// 连接成功
}

这里我们将FIL设置为"{MS Access}"就可以使用系统默认的MS Access数据源。而DBQ则指明了数据库文件的实际路径。

一旦打开连接,我们就可以执行各种SQL语句了:

// 插入记录
QSqlQuery query;
query.exec("INSERT INTO students (name, class, age) ""VALUES ('Raphael', '5A', 10)");// 查询记录 
model = new QSqlQueryModel(this);
model->setQuery("SELECT name, class, age FROM students");
ui->tableView->setModel(model);// 带参数查询
QString name = ui->nameEdit->text();
QString queryStr = "SELECT name, class, age ""FROM students WHERE name = ?";
query.prepare(queryStr);
query.addBindValue(name);
query.exec();

上面的代码为我们一一示范了如何在Qt中通过QSqlQuery类插入、查询和更新数据库记录。

使用很熟悉的SQL语句即可完成基本操作,另外QSqlQueryModel还提供了将SQL查询结果直接绑定到QTableView之类的Model/View UI控件上的便利功能。


总的来说,通过QODBC驱动,我们可以轻松高效地连接和操控各种数据库。这只是Qt数据库操作能力的一个简单示例,它的本领其实远不止如此,往下看,你就会慢慢体会到Qt数据库编程魅力了!


我们见识了Qt通过QODBC驱动连接和操作Access数据库的基本方法。而这仅仅是Qt数据库编程能力的一斑而已,接下来就让我们继续一同欣赏Qt大神们在这一领域内更为精深的绝世功夫。


三、QLite数据库,娇小玲珑胜无垠


在桌面和移动平台上,SQLite数据库无疑是最为常见和便捷的存储手段了。而要想在Qt中使用它,用这一手就绰绰有余:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("reader.db");
if (!db.open()) return;// 创建表格
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS books (""id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, ""title VARCHAR(40) NOT NULL, ""author VARCHAR(40) NOT NULL)");// 插入新记录            
query.prepare("INSERT INTO books (title, author) ""VALUES (:title, :author)");
query.bindValue(":title", title);
query.bindValue(":author", author);
query.exec();// 查询
query.prepare("SELECT id, title, author FROM books");
if (!query.exec()) qDebug() << query.lastError();
else {while(query.next()) {int id = query.value(0).toInt();QString title = query.value(1).toString();QString author = query.value(2).toString();}
}

Qt的SQLite支持是直接内置的,我们无需任何外部依赖,只需简单新建QSqlDatabase实例并指定"QSQLITE"驱动类型即可。

接下来我们可以像其他数据库一样,通过SQL语句自由创建和操作表格。使用QSqlQuery执行查询和插入,绑定参数,获取结果集等等都是理所当然的事情。

值得一提的是,SQLite在桌面/嵌入式平台中使用无需服务器进程,直接以文件形式跨平台访问,使用非常方便。这也是为什么Qt对其有着非常好的开箱即用支持。


四、封装数据库,万变不离其宗


任何一个出色的程序员,都不应当拘泥于底层API,而是要通过良好的设计模式和封装,构建出更高层次的数据库编程模型。看看Qt大神们是如何做到这一点的:

class DatabaseManager : public QObject
{Q_OBJECTpublic:explicit DatabaseManager(const QString &path, QObject *parent = nullptr);bool addBook(const Book &book);QList<Book> getAllBooks() const;private:QSqlDatabase m_db;bool openDatabase();bool createTables();};DatabaseManager::DatabaseManager(const QString &path, QObject *parent): QObject(parent), m_db(QSqlDatabase::addDatabase("QSQLITE"))
{m_db.setDatabaseName(path);
}bool DatabaseManager::openDatabase()
{if (m_db.open()) {return createTables();} else {qDebug() << "Error: Failed to connect to database.";return false;}
}
bool DatabaseManager::createTables()
{QSqlQuery query;// 创建图书表query.exec("CREATE TABLE IF NOT EXISTS books (""id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,""title VARCHAR(40) NOT NULL,""author VARCHAR(40) NOT NULL)");// 更多表创建语句...return true;
}bool DatabaseManager::addBook(const Book &book)
{QSqlQuery query;query.prepare("INSERT INTO books (title, author) VALUES (:title, :author)");query.bindValue(":title", book.title());query.bindValue(":author", book.author());return query.exec();
}QList<Book> DatabaseManager::getAllBooks() const
{QList<Book> books;QSqlQuery query("SELECT title, author FROM books");while (query.next()) {Book book;book.setTitle(query.value(0).toString());book.setAuthor(query.value(1).toString());books.append(book);}return books;
}

上面的代码定义了一个DatabaseManager类,它封装了SQLite数据库的打开、创建表格、添加数据和查询数据等常见操作。

在构造函数中,我们指定了要使用的数据库文件路径,之后的各种操作都将在该数据库文件上进行。

openDatabase()方法负责打开连接,如果连接成功则调用createTables()来创建所需的表格结构。

addBook()方法通过预处理SQL语句的方式插入新的Book记录,而getAllBooks()则查询出所有Book对象放入QList返回。

使用这种面向对象的封装方式,我们可以完全屏蔽底层的SQL细节,只需要编写简单的C++代码就能高效使用数据库了。这不仅使程序变得更加安全可靠,也大大提升了开发效率和可维护性。


五、数据库视图,化简为王道


除了对数据库进行底层CRUD(增删改查)操作外,构建视图也是数据库编程中一个常见的需求。而在Qt中,我们可以借助QSqlTableModel等高级接口,以优雅的方式管理数据库视图:

QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("books");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);if (!model->select()) {qDebug() << "Error selecting data: " << model->lastError().text();return;
}// 添加新记录
QSqlRecord record = model->record();
record.setValue("title", newTitle);
record.setValue("author", newAuthor);
if(!model->insertRecord(-1, record)) {qDebug() << "Error inserting record: " << model->lastError().text();
}  // 显示数据
ui->tableView->setModel(model);
ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked);
// 自动创建基本UI控件
ui->tableView->resizeColumnsToContents();

QSqlTableModel为我们提供了高度抽象和方便的数据库模型接口。通过setTable()方法,我们直接绑定到指定的数据表上。

查询select()会自动读取整张表的所有记录构建视图。而我们可以在获取的Model实例上自由地插入、修改记录,并通过setEditStrategy()控制何时提交这些修改到数据库。


将这个Model设置到QTableView之类的视图组件中,就可以获得一个完整的数据库视图界面。用户可以在其中双击单元格进行编辑,所有变更会被自动跟踪和更新。


这种以面向对象的方式在GUI中直接管理数据库视图的体验,绝对算是Qt数据库编程最大的亮点之一了。我们仅需要简单的几行代码,就能构建出直观高效的数据库CRUD界面。


结语:期待更多


通过上述介绍,我们已经初步领略了Qt大神们在数据库编程领域内的非凡造诣。当然,这只是冰山一角而已,他们实际上对数据库开发的掌控还远不止如此。

比如在SQL查询方面,Qt提供了强大的QSqlQueryModel帮助我们构建任意自定义的数据视图;再如在数据库报表输出方面,Qt Preview框架则为我们提供了现成的解决方案,等等。

这篇关于Qt5.14.2 无所不能的Qt数据库操作之旅的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/857257

相关文章

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Python ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言