Qt数据库操作
1. 建立连接:
QSqlDatabase,是一个值类,一个实例代表一个连接。 下面是支持的数据库:
Driver name DBMS
QDB2 IBM DB2 (version 7.1 and above)
QIBASE Borland InterBase
QMYSQL MySQL
QOCI Oracle Call Interface Driver
QODBC Open Database Connectivity (ODBC) -
Microsoft SQL Server and other ODBC-compliant databases
QPSQL PostgreSQL (versions 7.3 and above)
QSQLITE2 SQLite version 2
QSQLITE SQLite version 3
QTDS Sybase Adaptive Server
Note: obsolete from Qt 4.7
建立连接方法一:使用静态方法 addDatabase(),并用打开open():
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("acidalia");
db.setDatabaseName("customdb");
db.setUserName("mojito");
db.setPassword("J0a1m8");
bool ok = db.open();
方法二:使用默认,使用tables()查看数据库中的表.使用record(),查看字段。
QSqlDatabase db = QSqlDatabase::database();
示例:
void ConnectionWidget::refresh()
{
tree->clear();
QStringList connectionNames = QSqlDatabase::connectionNames();
bool gotActiveDb = false;
for (int i = 0; i < connectionNames.count(); ++i) {
QTreeWidgetItem *root = new QTreeWidgetItem(tree);
QSqlDatabase db = QSqlDatabase::database(connectionNames.at(i), false);
root->setText(0, qDBCaption(db));
if (connectionNames.at(i) == activeDb) {
gotActiveDb = true;
setActive(root);
}
if (db.isOpen()) {
QStringList tables = db.tables();
for (int t = 0; t < tables.count(); ++t) {
QTreeWidgetItem *table = new QTreeWidgetItem(root);
table->setText(0, tables.at(t));
}
}
}
if (!gotActiveDb) {
activeDb = connectionNames.value(0);
setActive(tree->topLevelItem(0));
}
}
//显示表格字体详情
void Browser::showMetaData(const QString &t)
{
QSqlRecord rec = connectionWidget->currentDatabase().record(t);
QStandardItemModel *model = new QStandardItemModel(table);
model->insertRows(0, rec.count());
model->insertColumns(0, 7);
model->setHeaderData(0, Qt::Horizontal, "Fieldname");
model->setHeaderData(1, Qt::Horizontal, "Type");
model->setHeaderData(2, Qt::Horizontal, "Length");
model->setHeaderData(3, Qt::Horizontal, "Precision");
model->setHeaderData(4, Qt::Horizontal, "Required");
model->setHeaderData(5, Qt::Horizontal, "AutoValue");
model->setHeaderData(6, Qt::Horizontal, "DefaultValue");
for (int i = 0; i < rec.count(); ++i) {
QSqlField fld = rec.field(i);
model->setData(model->index(i, 0), fld.name());
model->setData(model->index(i, 1), fld.typeID() == -1
? QString(QMetaType::typeName(fld.type()))
: QString("%1 (%2)").arg(QMetaType::typeName(fld.type())).arg(fld.typeID()));
model->setData(model->index(i, 2), fld.length());
model->setData(model->index(i, 3), fld.precision());
model->setData(model->index(i, 4), fld.requiredStatus() == -1 ? QVariant("?")
: QVariant(bool(fld.requiredStatus())));
model->setData(model->index(i, 5), fld.isAutoValue());
model->setData(model->index(i, 6), fld.defaultValue());
}
table->setModel(model);
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
updateActions();
}
###2.执行SQL: QT中的数据库操作,使用QSqlQuery进行增删改查。
bool QSqlQuery::exec(const QString & query)
对于SQLite, SQL语句只能一次执行一条,多的会执行失败。可以通过循环的方式来多次执行。
Example:
QSqlQuery query;
query.exec("INSERT INTO employee (id, name, salary) "
"VALUES (1001, 'Thad Beaumont', 65000)");
错误信息:
QSqlError QSqlQuery::lastError () const 返回最后产生的错误信息。
###3.批量执行
可以用绑定进行,多条相同结构的SQL语句:
QSqlQuery q;
q.prepare("insert into myTable values (?, ?)");
QVariantList ints;
ints << 1 << 2 << 3 << 4;
q.addBindValue(ints);
QVariantList names;
names << "Harald" << "Boris" << "Trond" << QVariant(QVariant::String);
q.addBindValue(names);
if (!q.execBatch())
qDebug() << q.lastError();
结果插入4条记录
1 Harald
2 Boris
3 Trond
4 NULL
###4.结果集:
执行的结果,在QSqlRecord中,每一个QSqlRecord为一条记录。使用next()遍历结果集,其它操作还有
seek(int n) :query指向结果集的第n条记录; first() :query指向结果集的第一条记录; last() :query指向结果集的最后一条记录; next() :query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录; previous() :query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录; record() :获得现在指向的记录; value(int n) :获得字段的值。其中n表示你查询的第n个字段, “select id, name from student”, 那么value(0)返回id字段的值,value(1)返回name字段的值。 at() :获得现在query指向的记录在结果集中的编号。
例子:
QSqlQuery q("select * from employees");
QSqlRecord rec = q.record();
qDebug() << "Number of columns: " << rec.count();
int nameCol = rec.indexOf("name"); // index of the field "name"
while (q.next())
qDebug() << q.value(nameCol).toString(); // output all names
###5.事务操作
bool QSqlDatabase::transaction() 返回TRUE,表示支持成功,否则失败。
事务可以保证一个复杂的操作的原子性。在Qt中,如果底层的数据库引擎支持事务,那么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();
###6.移除数据库
使用removeDatabase删除建立的连接:
{
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// Both "db" and "query" are destroyed because they are out of scope
QSqlDatabase::removeDatabase("sales"); // correct
参考: