Qt中的QtSQL模块提供了对数据库的支持,该模块中的众多类基本上分为三类:用户接口层,SQL接口层,驱动层。其中,驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁;SQL接口层提供了对数据库的访问;用户接口层实现了将数据库中的数据链接到窗口部件上,这样即使是不熟悉SQL也可以操作数据库。
一、基本步骤:
1.添加SQL数据库驱动
Qt默认支持一些驱动,也可以添加其他驱动
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug() << "Available drivers:";
QStringList drivers = QSqlDatabase::drivers(); //此处用QSqlDatabase类的静态函数drivers()来获取可用的驱动列表,然后将其遍历输出
foreach(QString driver, drivers)
qDebug() << driver;
return a.exec();
}
2.创建数据库连接:创建并打开一个或多个数据库连接(QSqlDatabase支持默认连接,如果应用程序中只需要一个数据库连接,那么使用默认连接是很方便的)。数据库连接使用连接名定义,而不是数据库名。在使用某些成员函数时需要制定一个连接名作为参数。
创建连接对象举例:
QsqlDatabase firstDB=QSqlDatabase::addDatabase("QMYSQL","first");
创建完连接之后,可以在任何地方使用QSqlDatabase::database()静态函数通过连接名称获取指向数据库连接的指针。
下面通过一个具体的例子看一下数据库连接的建立过程:
下面是代码:
#ifndef CONNECTION_H
#define CONNECTION_H
#include
#include
#include
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); //创建一个连接对象,这里使用的是默认连接
db.setDatabaseName(":memory:"); /*设置数据库名称时使用了“:memory:”,表明这个是建立在内存中的数据库 也就是说,这个数据库只在程序运行事有效,等程序运行结束时就会将其销毁 */
if (!db.open()) { /*open()函数用来打开数据库连接 如果打开失败则弹出提示对话框 */
QMessageBox::critical(0, "Cannot open database",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
QSqlQuery query; /*使用QSqlQuery创建一个student表, 并插入包含id和name两个字段的三条记录*/
query.exec("create table student (id int primary key, "
"name varchar(20))"); //primary key用来指定主键
query.exec("insert into student values(0, 'LiMing')");
query.exec("insert into student values(1, 'LiuTao')");
query.exec("insert into student values(2, 'WangHong')");
return true;
}
#endif // CONNECTION_H
#include
#include
#include
#include
#include "connection.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建数据库连接
if (!createConnection()) return 1;
// 使用QSqlQuery查询整张表
QSqlQuery query;
query.exec("select * from student");
while(query.next())
{
qDebug() << query.value(0).toInt() << query.value(1).toString();
}
return a.exec();
}
3.创建多个连接
可以同时建立多个连接,但要注意:不同的连接要有不同的连接名
#ifndef CONNECTION_H
#define CONNECTION_H
#include
#include
#include
static bool createConnection()
{
// 创建一个数据库连接,使用“connection1”为连接名
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");
db1.setDatabaseName("my1.db");
if (!db1.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 这里要指定连接
QSqlQuery query1(db1);
query1.exec("create table student (id int primary key, "
"name varchar(20))");
query1.exec("insert into student values(0, 'LiMing')");
query1.exec("insert into student values(1, 'LiuTao')");
query1.exec("insert into student values(2, 'WangHong')");
// 创建另一个数据库连接,要使用不同的连接名,这里是“connection2”
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");
db2.setDatabaseName("my2.db");
if (!db2.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 存在多个连接时,使用QSqlQuery要指定是使用哪个连接,这里要指定连接
QSqlQuery query2(db2);
query2.exec("create table student (id int primary key, "
"name varchar(20))");
query2.exec("insert into student values(10, 'LiQiang')");
query2.exec("insert into student values(11, 'MaLiang')");
query2.exec("insert into student values(12, 'ZhangBin')");
return true;
}
#endif // CONNECTION_H
#include
#include
#include
#include
#include "connection.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建数据库连接
if (!createConnection()) return 1;
// 使用QSqlQuery查询连接1的整张表,先要使用连接名获取该连接
QSqlDatabase db1 = QSqlDatabase::database("connection1"); //获取相应的数据库连接
QSqlQuery query1(db1);
qDebug() << "connection1:";
query1.exec("select * from student");
while(query1.next())
{
qDebug() << query1.value(0).toInt() << query1.value(1).toString();
}
// 使用QSqlQuery查询连接2的整张表
QSqlDatabase db2 = QSqlDatabase::database("connection2");
QSqlQuery query2(db2);
qDebug() << "connection2:";
query2.exec("select * from student");
while(query2.next())
{
qDebug() << query2.value(0).toInt() << query2.value(1).toString();
}
return a.exec();
}
二、执行SQL语句
1.执行一个查询
要执行一个SQl语句只需要创建一个QSqlQuery对象,然后调用QSqlQuery::exex()函数即可
例如:
QSqlQuery query;
query.exec("select * from student");
2.浏览结果集
此处可能用到很多函数,就不一一赘述了,可以去Data Types for Qt-supported Database Systems关键字对应的帮助文档找
下面是一个例子:
#ifndef CONNECTION_H
#define CONNECTION_H
#include
#include
#include
static bool createConnection()
{
// 创建一个数据库连接,使用“connection1”为连接名
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");
db1.setDatabaseName("my1.db");
if (!db1.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 这里要指定连接
QSqlQuery query1(db1);
query1.exec("create table student (id int primary key, "
"name varchar(20))");
query1.exec("insert into student values(0, 'LiMing')");
query1.exec("insert into student values(1, 'LiuTao')");
query1.exec("insert into student values(2, 'WangHong')");
// 创建另一个数据库连接,要使用不同的连接名,这里是“connection2”
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");
db2.setDatabaseName("my2.db");
if (!db2.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 这里要指定连接
QSqlQuery query2(db2);
query2.exec("create table student (id int primary key, "
"name varchar(20))");
query2.exec("insert into student values(10, 'LiQiang')");
query2.exec("insert into student values(11, 'MaLiang')");
query2.exec("insert into student values(12, 'ZhangBin')");
return true;
}
#endif // CONNECTION_H
#include
#include
#include
#include
#include "connection.h"
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建数据库连接
if (!createConnection()) return 1;
// 使用QSqlQuery查询连接1的整张表,先要使用连接名获取该连接
QSqlDatabase db1 = QSqlDatabase::database("connection1");
QSqlQuery query1(db1);
qDebug() << "connection1:";
query1.exec("select * from student");
while(query1.next())
{
qDebug() << query1.value(0).toInt() << query1.value(1).toString();
}
// 使用QSqlQuery查询连接2的整张表
QSqlDatabase db2 = QSqlDatabase::database("connection2");
QSqlQuery query2(db2);
qDebug() << "connection2:";
query2.exec("select * from student");
while(query2.next())
{
qDebug() << query2.value(0).toInt() << query2.value(1).toString();
}
int numRows;
// 先判断该数据库驱动是否支持QuerySize特性,如果支持,则可以使用size()函数,
// 如果不支持,那么就使用其他方法来获取总行数
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;
}
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”和“MaLiang”
qDebug() << "second field: " << field.name()
<< "field value: " << field.value().toString();
return a.exec();
}
3、插入、更新和删除记录
可以是单条操作,也可以是多条操作
如果多条操作时要用到占位符。有两种占位符:名称绑定和位置绑定
名称绑定:
query2.prepare("insert into student (id, name) values (:id, :name)");
int idvalue =100;
QString nameValue="ChenYun";
query.bindvalue(":id",idValue);
query.bindvalue(":name,nameValue");
query2.exec();
位置绑定:
query2.prepare("insert into student (id, name) values (?,?);
int idvalue =100;
QString nameValue="ChenYun";
query.bindvalue(idValue);
query.bindvalue(nameValue);
query2.exec();
#include
#include
#include
#include
#include "connection.h"
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建数据库连接
if (!createConnection()) return 1;
// 使用QSqlQuery查询连接1的整张表,先要使用连接名获取该连接
QSqlDatabase db1 = QSqlDatabase::database("connection1");
QSqlQuery query1(db1);
qDebug() << "connection1:";
query1.exec("select * from student");
while(query1.next())
{
qDebug() << query1.value(0).toInt() << query1.value(1).toString();
}
// 使用QSqlQuery查询连接2的整张表
QSqlDatabase db2 = QSqlDatabase::database("connection2");
QSqlQuery query2(db2);
qDebug() << "connection2:";
query2.exec("select * from student");
while(query2.next())
{
qDebug() << query2.value(0).toInt() << query2.value(1).toString();
}
int numRows;
// 先判断该数据库驱动是否支持QuerySize特性,如果支持,则可以使用size()函数,
// 如果不支持,那么就使用其他方法来获取总行数
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;
}
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”和“MaLiang”
qDebug() << "second field: " << field.name()
<< "field value: " << field.value().toString();
//插入
query2.exec("insert into student (id, name) values (100, 'ChenYun')");
query2.prepare("insert into student (id, name) values (?, ?)");
QVariantList ids;
ids << 20 << 21 << 22;
query2.addBindValue(ids);
QVariantList names;
names << "xiaoming" << "xiaoliang" << "xiaogang";
query2.addBindValue(names);
if(!query2.execBatch()) qDebug() << query2.lastError();
// 更新
query2.exec("update student set name = 'xiaohong' where id = 20");
// 删除
query2.exec("delete from student where id = 21");
return a.exec();
}