本文主要介绍了QSqlQuery的用法
数据库中的表格
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("qt-moduls-learning");
db.setUserName("root");
db.setPassword("");
if(db.open())
{
qDebug()<<"打开成功";
//创建表格
QSqlQuery query_creat_tb("CREATE TABLE IF NOT EXISTS tb_books(isbn VARCHAR( 30 ) NOT NULL ,book_name VARCHAR( 30 ) NOT NULL ,price VARCHAR( 5 ) NOT NULL)");
if(query_creat_tb.exec())
{
qDebug()<<"表创建成功";
//插入数据
QSqlQuery query_insert;
query_insert.exec("insert into tb_books values('20131101183101','Qt模块化笔记','18')");
query_insert.exec("insert into tb_books values('20131101183102','Qt模块化笔记2','19')");
}
//更新数据
QSqlQuery query_update("update tb_books set price='20' where isbn='20131101183102' ");
query_update.exec();
//查询数据
QSqlQuery query_select("SELECT * FROM tb_books");
while (query_select.next()) {
QString isbn = query_select.value(0).toString();
QString book_name = query_select.value(1).toString();
QString price = query_select.value(2).toString();
qDebug()<<isbn<<book_name<<price;
}
//删除数据
QSqlQuery query_delete("delete from tb_books where book_name='Qt模块化笔记2' ");
if(query_delete.exec())
{
qDebug()<<"删除成功";
}
}
在上面代码中,我们用QSqlQuery 类构造了很多语句,并分别执行了它们,比如
QSqlQuery query_insert;
query_insert.exec("insert into tb_books values('20131101183101','Qt模块化笔记','18')");
//与
QSqlQuery query_update("update tb_books set price='20' where isbn='20131101183102' ");
query_update.exec();
这两种构造方式都能够执行。但它们在事务处理时有些区别,等事务处理时再详细说。
我们在上面的语句中发现,似乎我们的数据库db和语句没联系的地方。其实它们是有联系的,这个db是一个”default“默认数据库,
看QSqlQuery公有函数,我们发现它的其中两种构造方式,
QSqlQuery(const QString & query = QString(), QSqlDatabase db = QSqlDatabase())
QSqlQuery(QSqlDatabase db)
我们上面使用的是第二种,只是省略了参数,这时,它默认就使用这个default数据库,也就是我们的db.
Constructs a QSqlQuery object using the database db. If db is invalid, the application's default database will be used.
——————————————————————
在上面语语句中,我们直接将字符串写在了语句中,也可以通过下面方式,将字符串“绑定”到语句中
1, named binding
QSqlQuery query;
query.prepare("INSERT INTO tb_books (isbn, book_name, price) "
"VALUES (:isbn, :book_name, :price)");
query.bindValue(":isbn", 20131101183102);
query.bindValue(":book_name", "书名");
query.bindValue(":price", 13);
query.exec();
2, positional binding:
QSqlQuery query;
query.prepare("INSERT INTO tb_books(isbn, book_name, price) "
"VALUES (?, ?, ?)");
query.addBindValue(20131101183102);
query.addBindValue("书名");
query.addBindValue(13);
query.exec();
______________________________________________
对于插入,更新,删除数据,exec()方法返回的都是true或false,可以通过这个返回值判断是否执行成功,但要注意的是,执行delete时,对于表中不存在要删除的数据,这条语句执行后,只要表存在,没有语句错误,它返回的是true。可以通过numRowsAffected()(语句影响的行数)来判断是否删除了或更改了记录。
例如
if(query.numRowsAffected()!= -1)//执行不成功,返回的是-1不是0
而对于select语句,返回的是结果集(可认为结果集是一页缩小版的表格,也可以认为是数组,认为是表格比较形象些……)。
类似的有 previous(), first(), last(), seek(int index, bool relative = false)
分别可取上一条,第一条,最后一条记录,及seek寻址到某一条
而int QSqlQuery::at() const
at()函数能返回当前所指结果在结果集中的索引
似乎这些都比较少用。
————————————————————————
下面将介绍结果处理:
while (query_select.next()) {
QString isbn = query_select.value(0).toString();
QString book_name = query_select.value(1).toString();
QString price = query_select.value(2).toString();
qDebug()<<isbn<<book_name<<price;
}
query_select.next()中的next()方法,获得结果集中的下一条记录,返回true或false,通过while语句,不断将指针移到下一位(可想象为,一个在表格左侧的“箭头”,不断指向下一行)
QString isbn = query_select.value(0).toString();
query_select.value(0),中的value(int a),方法,返回“箭头”所指行第a+1位列(字段)的值
从语句结果中获取值,value()是基于索引的,执行比较快(To retrieve values from a query, value() should be used since its index-based lookup is faster.)
另一种通过字段名获取值的方法,官方似乎不推荐用:
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
但我们可以发现其中rec.count();很有用,能算出结果数,因而,应该可以用于分页,这个以后讨论
————————————
总结
where(QSqlQuery.next) 遍历或exec()(numRowsAffected())的返回值判断是否成功,取某个字段的值用QSqlQuery.value(int)方法。