QT+QSLite数据库的使用

一、简单的数据库应用

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

你可能感兴趣的:(Qt实训)