QT学习笔记(十)数据库基础

SQL执行操作

QSqlQuery提供了对数据库记录的Select、Insert、Update、Delete操作。

SELECT操作:

 

QSqlQuery query;

query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

while (query.next()) {

    QString name = query.value(0).toString();

    int salary = query.value(1).toInt();

    qDebug() << name << salary;

}

 

通过QSqlQuery::next()、QSqlQuery::previous()、QSqlQuery::first()、QSqlQuery::last()、QSqlQuery::seek(),可以得到下一条、上一条、第一条、最后一条、任意一条记录的位置。

INSERT操作:

 

//单一插入数据

QSqlQuery query;

query.prepare("INSERT INTO employee (id, name, salary) "

                        "VALUES (:id, :name, :salary)");

query.bindValue(":id", 1001);

query.bindValue(":name", "Thad Beaumont");

query.bindValue(":salary", 65000);

query.exec();

//批量插入数据

QSqlQuery query;

query.prepare("insert into myTable values (?, ?)");

QVariantList ints;

ints << 1 << 2 << 3 << 4;

query.addBindValue(ints);

QVariantList names;

names << "Harald" << "Boris" << "Trond" << QVariant(QVariant::String);

query.addBindValue(names);

if (!query.execBatch())

    qDebug() << query.lastError();

 

UPDATE操作:

 

QSqlQuery query;

query.prepare("UPDATE employee SET salary = ? WHERE id = 1003");

query.bindValue(0, 70000);

query.exe();

 

DELETE操作:

 

QSqlQuery query;

query.exec("DELETE FROM employee WHERE id = 1007");

 

事务处理:

 

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();

 

如果数据库引擎支持事务处理,则函数QSqlDriver::hasFeature(QSqlDriver::Transactions)将返回 真。

可以通过调用QSqlDatabase::transaction()来初始化一个事务处理。之后执行你想在该事务处理的工作。

完了再执行QSqlDatabase::commit()来提交事务处理或QSqlDatabase::rollback()取消事务处理。

这里在举个QSqlDriver::hasFeature(QSqlDriver::QuerySize)例子,可以较快的统计查询记录行数。

 

QSqlQuery query;

int numRows;

query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

QSqlDatabase defaultDB = QSqlDatabase::database();

if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) {

    numRows = query.size();

} else {

     // this can be very slow

     query.last();

     numRows = query.at() + 1;

}

 

存储过程:

AsciiToInt()是数据库中的一个存储过程。

但我在网上以前好像看过说是SQL Server中的存储过程是通过"EXEC"完成的,而不是"CALL",这里我不确定!留下一个疑问吧~

 

QSqlQuery query;

query.prepare("CALL AsciiToInt(?, ?)");

query.bindValue(0, "A");

query.bindValue(1, 0, QSql::Out);

query.exec();

int i = query.boundValue(1).toInt(); // i is 65

 

■、使用SQL Model类

QSqlQueryModel:一个只读的读取数据库数据的模型。

QSqlTableModel:一个可读写的单一表格模型,可以不用写SQL语句。

QSqlRelationalTableModel:QSqlTableModel的一个子类,可多表关联在一起。

这些类都继承于QAbstractTableModel,而它们又都继承于QAbstractItemModel。

QSqlQueryModel 只读模式,基于SQL查询基础。

 

QSqlQueryModel model;

model.setQuery("SELECT * FROM employee");

for (int i = 0; i < model.rowCount(); ++i) {

    int id = model.record(i).value("id").toInt();

    QString name = model.record(i).value("name").toString();

    qDebug() << id << name;

}

 

QSqlTableModel 可对单一表操作,进行读写操作。

 

//读取数据

QSqlTableModel model;

model.setTable("employee");

model.setFilter("salary > 50000");

model.setSort(2, Qt::DescendingOrder);

model.select();

for (int i = 0; i < model.rowCount(); ++i) {

    QString name = model.record(i).value("name").toString();

    int salary = model.record(i).value("salary").toInt();

    qDebug() << name << salary;

}

//通过QSqlTableModel::setRecord()修改数据

for (int i = 0; i < model.rowCount(); ++i) {

    QSqlRecord record = model.record(i);

    double salary = record.value("salary").toInt();

    salary *= 1.1;

    record.setValue("salary", salary);

    model.setRecord(i, record);

}

model.submitAll();

//通过QSqlTableModel::setData()来update一条记录

model.setData(model.index(row, column), 75000);

model.submitAll();

//insert一条记录

model.insertRows(row, 1);

model.setData(model.index(row, 0), 1013);

model.setData(model.index(row, 1), "Peter Gordon");

model.setData(model.index(row, 2), 68500);

model.submitAll();

//delete一条记录

model.removeRows(row, 5);

model.submitAll();

 

函数QSqlTableModel::submitAll()确保记录写入数据库中。

QSqlRelationalTableModel 通过外键实现了多表关联。

 

//employee表中关联city表、country表。

model->setTable("employee");

model->setRelation(2, QSqlRelation("city", "id", "name"));

model->setRelation(3, QSqlRelation("country", "id", "name"));


/*下文不是原创、存属转载*/

结果集其实就是查询到的所有记录的集合,而在QSqlQuery类中提供了多个函数来操作这个集合,需要注意这个集合中的记录是从0开始编号的。最常用的有:

seek(int n) :query指向结果集的第n条记录。

first() :query指向结果集的第一条记录。

last() :query指向结果集的最后一条记录。

next() :query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录。

previous() :query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录。

record() :获得现在指向的记录。

value(int n) :获得属性的值。其中n表示你查询的第n个属性,比方我们使用“select * from student”就相当于“select id, name from student”,那么value(0)返回id属性的值,value(1)返回name属性的值。该函数返回QVariant类型的数据,关于该类型与其他类型的对应关系,可以在帮助中查看QVariant。

at() :获得现在query指向的记录在结果集中的编号。

需要说明,当刚执行完query.exec(“select * from student”);这行代码时,query是指向结果集以外的,我们可以利用query.next(),当第一次执行这句代码时,query便指向了结果集的第一条记录。当然我们也可以利用seek(0)函数或者first()函数使query指向结果集的第一条记录。但是为了节省内存开销,推荐的方法是,在query.exec(“select * from student”);这行代码前加上query.setForwardOnly(true);这条代码,此后只能使用next()和seek()函数

你可能感兴趣的:(QT)