QSqlQuery 如何与数据库 QSqlDatabase 关联 保持连接

结论:

只有使用Qt内置的默认连接名的时候,QSqlQuery才可以用空的构造函数,即如下是一一对应的:

mdb = QSqlDatabase::addDatabase("QSQLITE");

// 等价于 q(mdb)
QSqlQuery q;

q.exec("select *...");


又或者指定了连接名,必须要按如下配对:

mdb = QSqlDatabase::addDatabase("QSQLITE","MyConnectName");

// 不能用空构造函数,提示 database not open
QSqlQuery q(mdb);

q.exec("select *...");


结论对于子类化QSqlTableModel这样的模型同样有效,

如下是测试工程:


h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSqlDatabase>
#include <QSqlTableModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MyModel : public QSqlTableModel{
    Q_OBJECT

public:
    explicit MyModel(QObject *parent = nullptr, QSqlDatabase db = QSqlDatabase());

    void openQuery();
};
class MainWindow : public QMainWindow{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QSqlDatabase  mdb;
    MyModel *mmm;

protected:

private slots:
    void on_pushButton_clicked();
};
#endif // MAINWINDOW_H


CPP:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "utility.h"

#include <QDebug>
#include <QKeyEvent>
#include <QMessageBox>
#include <QSqlQuery>

#include <QSqlError>
#include <QString>

#ifdef _MSC_VER
#pragma execution_character_set("utf-8")
#endif

// 分别选择一个,编译并运行
#define CONN_NAME "connectionName"
//#define CONN_NAME

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    if(QSqlDatabase::contains(CONN_NAME)){
        T_INF <<"已经包含此连接名了:" << QString(CONN_NAME);
        mdb = QSqlDatabase::database(CONN_NAME);
    }
    else{
        QString conn = QString(CONN_NAME);

        if(conn.isEmpty()){
            T_INF << "使用默认NULL连接名";
            mdb = QSqlDatabase::addDatabase("QSQLITE");
        }
        else{
            T_INF << "使用自定义连接名:"<<conn;
            mdb = QSqlDatabase::addDatabase("QSQLITE",conn);
        }
        mdb.setDatabaseName("fileName.sqllite");
    }
    if (!mdb.open()) {
        QMessageBox::warning(0, QObject::tr("Database Error"),
                             mdb.lastError().text());
    }else{
        // 首次一定要指定 db
        QSqlQuery q(mdb);

        if(!mdb.tables().contains("student")){
            T_INF <<"新建表格";

            q.exec(QString("CREATE TABLE student (\
                           id INT PRIMARY KEY NOT NULL,\
                           name TEXT NOT NULL,\
                           age INT NOT NULL)"));

            q.exec(QString("INSERT INTO student VALUES(1,'zhangsan',16)"));
            q.exec(QString("INSERT INTO student VALUES(2,'lishi',17)"));
            q.exec(QString("INSERT INTO student VALUES(3,'wangwu',16)"));
            q.exec(QString("INSERT INTO student VALUES(4,'zhaolei',15)"));
        }else{
            T_INF <<"已经有表格了";
        }

    }

    // 建立model
    mmm = new MyModel(this,mdb);
}

MainWindow::~MainWindow()
{
    mdb.close();
    delete ui;
}

// add db
void MainWindow::on_pushButton_clicked()
{
    if(QSqlDatabase::contains(CONN_NAME)){
        T_INF <<"已经包含此连接名了:" << QString(CONN_NAME);
        mdb = QSqlDatabase::database(CONN_NAME);
    }

    QSqlQuery q;

    q.exec("select * from tb1"); // 故意用错表
    if(q.last()){
        T_INF <<"有数据:"<<q.at()+1;
    }else{
        T_ERR <<"没数据了";
    }

    T_INF <<"用model来查询看看 ==>> ";

    mmm->openQuery();
}

MyModel::MyModel(QObject *parent, QSqlDatabase db):QSqlTableModel(parent,db)
{

}

void MyModel::openQuery()
{
    QSqlQuery q;

    if(!q.exec("select * from student")){
        T_ERR <<"exec sql 错误";
    }
    if(q.last()){
        T_INF <<"有数据:"<<q.at()+1;
    }else{
        T_ERR <<"没数据了";
    }
}


分别选择CONN_NAME一个编译并运行,结果如下:


1、CONN_NAME是字符串,结果:

[ TRACE ][file://..\mainwindow.cpp:38:MainWindow]使用自定义连接名:"connectionName"
[ TRACE ][file://..\mainwindow.cpp:63:MainWindow]已经有表格了
[ TRACE ][file://..\mainwindow.cpp:82:on_pushButton_clicked]已经包含此连接名了:"connectionName"
QSqlQuery::exec: database not open
[ TRACE ][file://..\mainwindow.cpp:92:on_pushButton_clicked]没数据了
[ TRACE ][file://..\mainwindow.cpp:95:on_pushButton_clicked]用model来查询看看 ==>> 
QSqlQuery::exec: database not open
[ TRACE ][file://..\mainwindow.cpp:110:openQuery]exec sql 错误
[ TRACE ][file://..\mainwindow.cpp:115:openQuery]没数据了


2、选择CONN_NAME为空,结果:

[ TRACE ][file://..\mainwindow.cpp:34:MainWindow]使用默认NULL连接名
[ TRACE ][file://..\mainwindow.cpp:63:MainWindow]已经有表格了
[ TRACE ][file://..\mainwindow.cpp:82:on_pushButton_clicked]已经包含此连接名了:""
[ TRACE ][file://..\mainwindow.cpp:92:on_pushButton_clicked]没数据了
[ TRACE ][file://..\mainwindow.cpp:95:on_pushButton_clicked]用model来查询看看 ==>> 
[ TRACE ][file://..\mainwindow.cpp:113:openQuery]有数据:4


本文为3YL原创,转载无需联系,但请注明来自labisart.com。

原创文章不易,如果觉得有帮助,可打赏或点击右侧广告支持:

查看打赏记录

发表评论请遵守党国法律!后台审核后方可显示!
  • 最新评论
  • 总共0条评论
  • Blog v1.1© 2024 labisart.com 版权所有 | 联系:labartwork@163.com