1.数据库
Qt SQL模块的类分层
————————————————————————————————————————————————————————————————————————————————————————————————
层 | 对应的类
————————————|———————————————————————————————————————————————————————————————————————————————————
用户接口层 | QSqlQueryModel、QSqulTableModel和QSqlRelationalTableMode
————————————|———————————————————————————————————————————————————————————————————————————————————
SQL接口层 | QSqlDatabase、QSqlQuery、QSqulError、QSqlField、QSqlIndex和QSqlRecord
————————————|———————————————————————————————————————————————————————————————————————————————————
驱动层 | QSqlDriver、QSqlDriverCreator、QSqlDriverCreator、QSqlDriverPlugin和QSqlResult
————————————————————————————————————————————————————————————————————————————————————————————————
说明:
- 驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁;
- SQL接口层提供了对数据库的访问,其中的QSqlDatabase类用来创建连接,QSqlQuery类可以使用SQL语句来实现与数据库交互,其他几个类对该层提供了支持;
- 用户接口层的几个类实现了将数据库中的数据链接到窗口部件上。
(1)连接数据库
①SQL数据库驱动
Qt中包含的数据库驱动
驱动名称 数据库
QDB2 IBM DB2(7.1版本或者以上版本)
QIBASE Borland InterBase
QOCI MySQL
QODBC Oracle Database Connectivity(ODBC)-微软SQL Server和其他ODBC兼容数据库
QPSQL PostgreSQL(7.3版本或者更高)
QSQLITE2 SQLite版本2
QSQLITE SQLite版本3
QTDS Sybase Adaptive Server(注:从Qt4.7开始已经过时)
②创建数据库连接
原型:QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String( defaultConnection ))
例如:
//未指定addDatabase()函数的第二个参数即连接名,这样建立的是默认连接
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); //创建连接对象
db.setHostName("bigblue"); //初始化主机名
db.setDatabaseName("flightdb"); //初始化数据库名
db.setUserName("acarlson"); //初始化用户名
db.setPassword("1uTbSbAs"); //初始化密码
bool ok = db.open(); //打开该链接以便使用
//指定连接名和连接名称
QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL","first");
QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL","second");
//未指定连接名称,会返回默认连接
QSqlDatabase defaultDB = QSqlDatabase::database();
QSqlDatabase firstDB = QSqlDatabase::database("first");
QSqlDatabase secondDB = QSqlDatabase::database("second");
要移除一个数据库连接,需要先使用QSqlDatabase::close()关闭数据库,然后使用静态函数QSqlDatabase::removeDatabase()移除该连接。
(2)执行SQL语句
①执行一个查询
QSqlQuery类提供了一个接口,用于执行SQL语句和浏览查询的结果集。
要执行一个SQL语句,只需要简单的创建一个QSqlQuery对象,然后调用QSqlQuery::exec()函数即可。
例如:
QSqlQuery query;
query.exec("select * from student");
在QSqlQuery的构造函数中可以接收一个可选的QSqlDatabase对象来指定使用的是哪一个数据库连接,当没有连接时,就是使用默认连接。
如果发生了错误,那么exec()函数会返回false,可以使用QSqlQuery::lastError()来获取错误信息。
②浏览结果集
QSqlQuery提供了对结果集的访问,可以一次访问一条记录。
当执行完exec()函数后,QSqlQuery的内部指针会位于第一条记录前面的位置。
必须调用一次QSqlQuery::next()函数来使其前进到第一条记录,然后可以重复使用next()函数来访问其他的记录,直到该函数的返回值为false。
例如可以使用以下代码来遍历一个结果集:
while(query.next())
{
qDebug() << query.value(0).toInt() << query.value(1).toString();
}
③插入、更新和删除记录
插入一条记录:query2.exec(“insert into student (id, name) values (100, ‘ChenYun’)”);
如果想在同一时间插入多条记录,那么一个有效的方法就是将查询语句和真实的值分离,这可以使用占位符来完成。
使用占位符:
//Qt支持两种占位符:名称绑定和位置绑定。
//名称绑定
query2.prepare("insert into student (id, name) values (:id, :name)");
int idValue = 100;
QString nameValue = "ChenYun";
query2.bindValue(":id", idValue);
query2.bindValue(":name", nameValue);
query2.exec();
//位置绑定
query2.prepare("insert into student (id, name) values (?, ?)");
int idValue = 100;
QString nameValue = "ChenYun";
query2.addBindValue(idValue);
query2.addBindValue(nameValue);
query2.exec();
当要插入多条记录时,只需要调用QSqlQuery::prepare()一次,然后使用多次bindValue()或者addBindValue()函数来绑定需要的数据,最后调用一次exec()函数就可以了。
批处理:
例如:
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();
//这里先使用了占位符,不过每一个字段值都绑定了一个列表,最后只要调用execBatch()函数即可。
④事务
事务可以保证一个复杂的操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,是不可分割的工作单位。
如果底层的数据库引擎支持事务,QSqlDriver::hasFeature(QSqlDriver::Transactions)会返回true。
可以使用QSqlDatabase::transaction()来启动一个事务,然后编写希望在事务中执行的SQL语句,最后调用QSqlDatabase::commit()提交或者QSqlDatabase::rollback()回滚。使用事务必须在创建查询以前就开始事务。
例如:
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");
if (query.next()) {
int employeeId = query.value(0).toInt();
query.exec("INSERT INTO project (id, name, ownerid) "
"VALUES (201, 'Manhattan Project', "
+ QString::number(employeeId) + ')');
}
QSqlDatabase::database().commit();
(3)使用SQL模型类
①SQL查询模型
QSqlQueryModel提供了一个基于SQL查询的只读模型。
介绍略。
②SQL表格属性
QSqlTableModel提供了一个一次只能操作一个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。
SQL表格模型的编辑策略
————————————————————————————————————————————————————————————————————————————————————————————————————————
常量 |描述
————————————————————————————————|———————————————————————————————————————————————————————————————————————
QSqlTableModel::OnFieldChange |所有对模型的改变都会立即应用到数据库
————————————————————————————————|———————————————————————————————————————————————————————————————————————
QSqlTableModel::OnRowChange |对一条记录的改变会在用户选择另一条记录时被应用
————————————————————————————————|———————————————————————————————————————————————————————————————————————
QSqlTableModel::OnManualSubmit |所有的改变都会在模型中进行缓存,直到调用submitALl()或者revertAll()函数
————————————————————————————————————————————————————————————————————————————————————————————————————————
③SQL关系表格模型
QSqlRelationalTableModel继承自QSqlTableModel,并且对其进行了扩展,提供了对外键的支持。
一个外键就是一个表中的一个字段和其他表中的主键字段之间的一对一的映射。
2.XML
略。