最近学习了Qt5下的数据库操作,特做此笔记,总结一下,与大家共勉,其中许多内容借鉴于霍亚飞老师的书籍——《Qt Creator快速入门(第二版)》。
软件版本:Qt Creator 3.1.2(opensource)
Based on Qt 5.3.1(MSVC 2010, 32 bit)
Built on Jun 23 2014 at 04:13:10
1. 数据库简介
Qt中的 QtSql 模块提供了对数据库的支持,该模块中的众多类基本上可以分为3层,如下表所示。
层次 | Qt提供的类 |
---|---|
用户接口层 | QSqlQueryModel、QSqlTableModel 和 QSqlRelationalTableModel |
SQL接口层 | QSqlDatabase、QSqlQuery、QSqlError、QSqlField、QSqlIndex 和 QSqlRecord |
驱动层 | QSqlDriver、QSqlDriverCreator< T >、QSqlDriverCreatorBase、QSqlDriverPlugin 和 QSqlResult |
其中,驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁;
SQL接口层提供了对数据库的访问,其中的 QSqlDatabase 类用来创建连接,QSqlQuery 类可以使用 SQL 语句来实现与数据库交互,其他几个类对该层提供了支持;用户接口层的几个类实现了将数据库中的数据链接到窗口部件上,这些类是使用 模型/视图 框架实现的,它们是更高层次的抽象,即便不熟悉 SQL 也可以操作数据库。如果要使用 QtSql 模块中的这些类,需要在项目文件(.pro 文件)中添加“QT+=sql”这行代码。对应数据库部分的内容,可以在帮助中查看 SQL Programming 关键字。
2. QqlDatabase 类中的函数
class Q_SQL_EXPORT QSqlDatabase
{
public:
QSqlDatabase();
QSqlDatabase(const QSqlDatabase &other);
~QSqlDatabase();
QSqlDatabase &operator=(const QSqlDatabase &other);
bool open();
bool open(const QString& user, const QString& password);
void close();
bool isOpen() const;
bool isOpenError() const;
QStringList tables(QSql::TableType type = QSql::Tables) const;
QSqlIndex primaryIndex(const QString& tablename) const;
QSqlRecord record(const QString& tablename) const;
QSqlQuery exec(const QString& query = QString()) const;
QSqlError lastError() const;
bool isValid() const;
bool transaction();
bool commit();
bool rollback();
void setDatabaseName(const QString& name);
void setUserName(const QString& name);
void setPassword(const QString& password);
void setHostName(const QString& host);
void setPort(int p);
void setConnectOptions(const QString& options = QString());
QString databaseName() const;
QString userName() const;
QString password() const;
QString hostName() const;
QString driverName() const;
int port() const;
QString connectOptions() const;
QString connectionName() const;
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
QSqlDriver* driver() const;
QT_STATIC_CONST char *defaultConnection;
static QSqlDatabase addDatabase(const QString& type,
const QString& connectionName = QLatin1String(defaultConnection));
static QSqlDatabase addDatabase(QSqlDriver* driver,
const QString& connectionName = QLatin1String(defaultConnection));
static QSqlDatabase cloneDatabase(const QSqlDatabase &other, const QString& connectionName);
static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection),
bool open = true);
static void removeDatabase(const QString& connectionName);
static bool contains(const QString& connectionName = QLatin1String(defaultConnection));
static QStringList drivers();
static QStringList connectionNames();
static void registerSqlDriver(const QString &name, QSqlDriverCreatorBase *creator);
static bool isDriverAvailable(const QString &name);
protected:
explicit QSqlDatabase(const QString& type);
explicit QSqlDatabase(QSqlDriver* driver);
private:
friend class QSqlDatabasePrivate;
QSqlDatabasePrivate *d;
};
如上所示摘自Qt5中的 < qsqldatabase.h >
3. QqlDatabase 类中的部分函数代码演示
下面都使用了 SQLite 这个数据库作为例子
工程项目文件(.pro)中添加如下:
QT += sql
包含以下头文件:
#include <QSqlDatabase>
#include <QStringList>
#include <QDebug>
#include <QCoreApplication>
#include <QSqlError>
代码:
//获得Qt5中可用的数据库插件,调用静态成员函数 drivers()
QStringList drivers = QSqlDatabase::drivers();
foreach (QString driver, drivers) {
qDebug() << driver;
}
//创建数据库连接,调用静态成员函数 addDatabase()
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");//使用默认连接名
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");//使用“connection2”为连接名
QSqlDatabase db3 = QSqlDatabase::addDatabase("QSQLITE", "connection3");//使用“connection3”为连接名
//如果数据库连接列表包含该连接名,则返回true,否则返回false。这里明显都包含,因为前面都添加过了
qDebug() << QSqlDatabase::contains() << QSqlDatabase::contains("connection2") << QSqlDatabase::contains("connection3");
//获得所有的连接名,调用静态成员函数 connectionNames()
QStringList connectnames = QSqlDatabase::connectionNames();
foreach (QString connectname, connectnames) {
qDebug() << connectname;
}
//设置数据库的路径和名字,这里路径设置为在.exe文件的目录下
QString dbpath = QCoreApplication::applicationDirPath();//获取.exe文件的目录
db1.setDatabaseName(dbpath + "/" + "db1.db");//设置数据库名字为 db1.db
db2.setDatabaseName(dbpath + "/" + "db2.db");//设置数据库名字为 db2.db
db3.setDatabaseName(dbpath + "/" + "db3.db");//设置数据库名字为 db3.db
//设置数据库的主机名、用户名和密码
db1.setHostName("bigblue");
db1.setUserName("try");
db1.setPassword("123456");
//使用当前连接名打开数据库连接。如果该路径下不存在此名称的数据库,则新建该名称的数据库
//如果都打开成功,你会发现.exe文件目录下出现了 db1.db、 db2.db、 db3.db
if(!db1.open())//打开失败
{
qDebug() << db1.lastError();//调用成员函数 lastError() 检索错误信息
}
if(!db2.open())
{
qDebug() << db2.lastError();
}
if(!db3.open())
{
qDebug() << db3.lastError();
}
//根据已有数据库拷贝一份数据库,同时设置其连接名
QSqlDatabase db4 = QSqlDatabase::cloneDatabase(db2, "connection4");
db4.setDatabaseName(dbpath + "/" + "db4.db");
if(!db4.open())
{
qDebug() << db4.lastError();
}
//关闭数据库连接,释放所获取的任何资源,并使与数据库一起使用的任何现有QSqlQuery对象失效
//这也将影响此QSqlDatabase对象的副本
if(db1.isOpen())
{
db1.close();
qDebug() << "close db1.db, free anything about it";
}
if(db2.isOpen())
{
db2.close();
qDebug() << "close db2.db, free anything about it";
}
if(db3.isOpen())
{
db3.close();
qDebug() << "close db3.db, free anything about it";
}
if(db4.isOpen())
{
db4.close();
qDebug() << "close db4.db, free anything about it";
}
4. 总结
还有好些函数没有测试,有兴趣的可以一个个去尝试。有时间的话会继续添加该内容笔记。