一、简单的数据库应用
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//创建一个SQLite数据库连接
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
//数据库连接命名
db.setDatabaseName(":memory:");
//打开数据库
if(!db.open()) return false;
//以下执行相关sql语句
QSqlQuery query;
//新建student表,id设置为主键,还有一个name项
query.exec("create table student(id int primary key,name varchar)");
//向表中插入3条记录
query.exec("insert into student values(1,'xiaogang')");
query.exec("insert into student values(2,'xiaoming')");
query.exec("insert into student values(3,'xiaohong')");
//查找表中id >=2 的记录的id项和name项的值
query.exec("select id,name from student where id >= 2");
//query.next()指向查找到的第一条记录,然后每次后移一条记录
while(query.next())
{
//query.value(0)是id的值,将其转换为int型
int value0 = query.value(0).toInt();
QString value1 = query.value(1).toString();
//输出两个值
qDebug() << value0 << value1 ;
}
return a.exec();
}
这里使用了SQLite数据库,连接名为“:memory:”表示这是建立在内存中的数据库,也就是说该数据库只在程序运行期间有效。如果需要保存该数据库文件,我们可以将它更改为实际的文件路径。
二、创建数据库连接
connection.h
#ifndef CONNECTION_H
#define CONNECTION_H
#include
#include
#include
#include
//建立连接函数
static bool createConnection()
{
//首先创建一个SQLite数据库的默认连接
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
//设置数据库名称使用":memory:",表明是建立在内存中的数据库
db.setDatabaseName(":memory:");
//使用open()函数打开数据库
if (!db.open()) {
//打开失败弹出提示对话框
QMessageBox::critical(0, qApp->tr("Cannot open database"),qApp->tr("Unable to establish a database connection."), QMessageBox::Cancel);
return false;
}
//使用QSqlQuery创建了一个student表,并插入了包含id和name两个字段的五条记录
QSqlQuery query;
query.exec("create table student (id int primary key, "
"name varchar(20))");
query.exec("insert into student values(0, 'first')");
query.exec("insert into student values(1, 'second')");
query.exec("insert into student values(2, 'third')");
query.exec("insert into student values(3, 'fourth')");
query.exec("insert into student values(4, 'fifth')");
return true;
}
#endif // CONNECTION_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
query.exec("select *from student");
while (query.next())
{
qDebug() << query.value(0).toInt()
<< query.value(1).toString();
}
/*
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()函数。
*/
}
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
query.exec("select *from student");
qDebug() << "exec next() :";
//开始就先执行一次next()函数,那么query指向结果集的第一条记录
if(query.next())
{
//获取query所指向的记录在结果集中的编号
int rowNum = query.at();
//获取每条记录中字段(即列)的个数
int columnNum = query.record().count();
//获取"name"字段所在列的编号,列从左向右编号,最左边的编号为0
int fieldNo = query.record().indexOf("name");
//获取id字段的值,并转换为int型
int id = query.value(0).toInt();
//获取name字段的值
QString name = query.value(fieldNo).toString();
//将结果输出
qDebug() << "rowNum is : " << rowNum
<< " id is : " << id
<< " name is : " << name
<< " columnNum is : " << columnNum;
//定位到结果集中编号为2的记录,即第三条记录,因为第一条记录的编号为0
qDebug() << "exec seek(2) :";
if(query.seek(2))
{
qDebug() << "rowNum is : " << query.at()
<< " id is : " << query.value(0).toInt()
<< " name is : " << query.value(1).toString();
}
//定位到结果集中最后一条记录
qDebug() << "exec last() :";
if(query.last())
{
qDebug() << "rowNum is : " << query.at()
<< " id is : " << query.value(0).toInt()
<< " name is : " << query.value(1).toString();
}
}
}
三、在SQL语句中使用变量
根据spinBox的值查询
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
int id = ui->spinBox->value();
query.exec(QString("select name from student where id = %1").arg(id));
query.next();
QString name = query.value(0).toString();
qDebug() << name;
}
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
query.prepare("insert into student (id, name) "
"values (:id, :name)");
//这里还可以这样写:
//query.prepare("insert into student (id, name) "
// "values (?, ?)");
query.bindValue(0, 5);
query.bindValue(1, "sixth");
query.exec();//一定要执行
query.exec("select * from student");
query.last();
int id = query.value(0).toInt();
QString name = query.value(1).toString();
qDebug() << id << name;
// 当用ODBC的表示方法时,我们也可以将编号用实际的占位符代替,如下:
// query.prepare("insert into student (id, name) "
// "values (:id, :name)");
// query.bindValue(":id", 5);
// query.bindValue(":name", "sixth");
// query.exec();
}
以下实现通过Spin Box的值来进行查询(不是很懂)。
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
query.prepare("select name from student where id = ?");
int id = ui->spinBox->value();
query.addBindValue(id);
query.exec();
query.next();
qDebug() << query.value(0).toString();
}
void Widget::on_pushButton_clicked()
{
QSqlQuery query;
query.prepare("insert into student values (?, ?)");
QVariantList ints;
ints << 10 << 11 << 12 << 13;
query.addBindValue(ints);
QVariantList names;
// 最后一个是空字符串,应与前面的格式相同
names << "xiaoming" << "xiaoliang" << "xia0gang" << QVariant(QVariant::String);
query.addBindValue(names);
if (!query.execBatch()) //进行批处理,如果出错就输出错误
{
qDebug() << query.lastError();
}
//下面输出整张表
QSqlQuery q;
q.exec("select * from student");
while(q.next())
{
int id = q.value(0).toInt();
QString name = q.value(1).toString();
qDebug() << id << name;
}
// 我们在程序中利用列表存储了同一字段的多个值,然后进行了值绑定。最后执行
// execBatch()函数进行批处理。注意程序中利用QVariant(QVariant::String)
// 来输入空值NULL,因为前面都是QString类型的,所以这里要使用QVariant::String
// 使格式一致化。
}
四、SQL查询模型QSqlQueryModel*
void Widget::on_pushButton_clicked()
{
QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select *from student");
model->setHeaderData(0, Qt::Horizontal, tr("id"));
model->setHeaderData(1, Qt::Horizontal, tr("name"));
QTableView *view = new QTableView;
view->setModel(model);
view->show();
}
void Widget::on_pushButton_clicked()
{
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("select *from student");
model->setHeaderData(0, Qt::Horizontal, tr("id"));
model->setHeaderData(1, Qt::Horizontal, tr("name"));
QTableView *view = new QTableView;
view->setModel(model);
//自适应宽度
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
view->show();
QSqlQuery query = model->query();
query.exec("insert into student values (10,'yafei10')");
model->setQuery("select * from student"); //再次查询整张表
view->show(); //再次进行显示
}
更改字体颜色,并且可编辑
#ifndef MYSQLQUERYMODEL_H
#define MYSQLQUERYMODEL_H
#include
class MySqlQueryModel : public QSqlQueryModel
{
Q_OBJECT
public:
explicit MySqlQueryModel(QObject *parent = 0);
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const;
private:
bool setName(int studentId, const QString &name);
void refresh();
};
#endif // MYSQLQUERYMODEL_H
#include "mysqlquerymodel.h"
#include
#include
MySqlQueryModel::MySqlQueryModel(QObject *parent) :
QSqlQueryModel(parent)
{
}
Qt::ItemFlags MySqlQueryModel::flags(
const QModelIndex &index) const //返回表格是否可更改的标志
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 1) //第二个字段可更改
flags |= Qt::ItemIsEditable;
return flags;
}
bool MySqlQueryModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
//添加数据
{
if (index.column() < 1 || index.column() > 2)
return false;
QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
int id = data(primaryKeyIndex).toInt(); //获取id号
clear();
bool ok;
if (index.column() == 1) //第二个字段可更改
ok = setName(id, value.toString());
refresh();
return ok;
}
void MySqlQueryModel::refresh() //更新显示
{
setQuery("select * from student");
setHeaderData(0, Qt::Horizontal, QObject::tr("id"));
setHeaderData(1, Qt::Horizontal, QObject::tr("name"));
}
//添加name字段的值
bool MySqlQueryModel::setName(int studentId, const QString &name)
{
QSqlQuery query;
query.prepare("update student set name = ? where id = ?");
query.addBindValue(name);
query.addBindValue(studentId);
return query.exec();
}
//更改数据显示样式
QVariant MySqlQueryModel::data(const QModelIndex &index, int role) const
{
QVariant value = QSqlQueryModel::data(index, role);
//第一个字段的字体颜色为红色
if (role == Qt::TextColorRole && index.column() == 0)
return qVariantFromValue(QColor(Qt::red));
return value;
}
void MainWindow::on_pushButton_clicked()
{
QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select* from student");
model->setHeaderData(0, Qt::Horizontal, tr("id"));
model->setHeaderData(1, Qt::Horizontal, tr("name"));
QTableView *view = new QTableView;
view->setModel(model);
view->show();
//创建自己模型的对象
MySqlQueryModel *myModel = new MySqlQueryModel(this);
myModel->setQuery("select * from student");
myModel->setHeaderData(0, Qt::Horizontal, tr("id"));
myModel->setHeaderData(1, Qt::Horizontal, tr("name"));
QTableView *view1 = new QTableView;
view1->setWindowTitle("mySqlQueryModel"); //修改窗口标题
view1->setModel(myModel);
view1->show();
}