Qt5之使用sqlite3数据库

1、效果

Qt5之使用sqlite3数据库_第1张图片


2、添加 sql引用

.pro文件 添加 下面的引用

QT += sql

3、创建数据库链接

// 数据库连接
    QSqlDatabase    sqliteDatabase;

4、保存数据库连接

我使用了自定义数据库链接名

 // 解除对数据库的默认连接
    bool isContain      = QSqlDatabase::contains(databaseConnectionName);
    if (true           == isContain)
    {
        sqliteDatabase  = QSqlDatabase::database(databaseConnectionName);
    }
    else
    {
        sqliteDatabase  = QSqlDatabase::addDatabase( "QSQLITE", databaseConnectionName);
    }

使用SQLITE的数据库驱动如下:

sqliteDatabase  = QSqlDatabase::addDatabase( "QSQLITE", databaseConnectionName);

其中, databaseConnectionName值如下

// 设置数据库连接名
    databaseConnectionName    = QString("helperConnection");

3、数据库的打开与关闭

    // 2、检查数据库是否关闭
    bool isOpen         = sqliteDatabase.isOpen();

    // 1.1 若已经打开数据库
    if (true            == isOpen)
    {
        // 1.1.1 关闭数据库
        sqliteDatabase.close();
    }
    else
    {
        // 1.1.2 数据库没有打开
#ifdef QT_DEBUG
        qDebug() << "数据库没有打开, 什么也不做";
#endif
    }

4、指定数据库名

关联数据库文件 和 打开数据库

// 1、尝试打开新选择的文件,
    sqliteDatabase.setDatabaseName(fileName);

    // 1.1 尝试打开数据库
    bool openFlag           = sqliteDatabase.open();

    // 1.2  若打开失败
    if (false               == openFlag)
    {
        QMessageBox::critical(this, tr("warning"),  tr("open database file err"));
        return;
    }
取sqlite3数据库文件中的所有表名
// 2、读取数据库中的所有表名, 排除重复的表名 和 sqlite_sequence
    QStringList tableNameList   = sqliteDatabase.tables();
#ifdef QT_DEBUG
    qDebug() << "查询的表名的个数= " << tableNameList.count();
#endif

    ///------------------------------------------------------------------
    // 读取数据库中的表名
    realTableName.clear();
    int realTableNameCount  = 0;
    bool isFind             = false;
    foreach (QString name, tableNameList)
    {
        isFind              = false;
        // sqlite_sequence 排除
        if ( QString("sqlite_sequence") == name)
        {
            continue;
        }

        realTableNameCount  = realTableName.count();
        // 若已经存在了,跳过
        for (int i = 0; i < realTableNameCount; i++)
        {
            // 已经存在
            if (name    == realTableName.at(i))
            {
                isFind  = true;
                break;
            }
        }
        // 若没找到, 说名name是唯一存在的, 则添加到数组
        if (false       == isFind)
        {
            // 若没有找到,则添加到列表中
            realTableName << name;
        }
    }
数据库文件中,存在重复的表名, 代码中去掉了重复表名,同时排除了 表 
sqlite_sequence

5、创建QSqlTableModel

声明

 QSqlTableModel  *sqlTableModel[he_tableview_count_10];

创建

for (int i = 0; i < he_tableview_count_10; i++)
    {
        sqlTableModel[i]    = new QSqlTableModel(NULL, sqliteDatabase);
        sqlTableModel[i]->setEditStrategy(QSqlTableModel::OnManualSubmit);
    }

我用的是 QTableView 与 QSqlTableModel 关联 读写数据库, 每一个QSqlTableModel 对应一个 QTableView

6、使用QSqlTableModel 

    数据库打开后,即可使用model读取数据库数据了

// 3、读取数据库表中的数据,添加到tableView中显示
    int sqlTableModelIndex  = 0;
    int index    = 0;
    foreach (QString name, realTableName)
    {
        QSqlTableModel *pModel      = sqlTableModel[sqlTableModelIndex++];

        // 设置连接的数据库名
        pModel->setTable(name);

        pModel->setSort(0,  Qt::AscendingOrder);

        // 设置手动提交
        pModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

        // 查询数据
        pModel->select();
        // 添加到tableview
        tableViewArr[index]->setModel(pModel);

        // 添加到tabwidget
        tabWidget->addTab(tableViewArr[index], name);

        // 设置tab
        tabWidget->setTabIcon(index, QIcon(":/res/ico/tab/tab"));

        // 解除对256行的限制
        while(pModel->canFetchMore())
        {
            pModel->fetchMore();
        }

        // 计数器 +1
        index   += 1;

        // 只显示第一张表的内容
        if (1 == index)
        {
            break;
        }
    }

我这里做了限制, 只显示  数据库中的第一张表的内容, 去掉下面的代码,即可读取数据库中所有表的内容

 // 只显示第一张表的内容
        if (1 == index)
        {
            break;
        }

QSqlTableModel,  若数据库表中的数据 超过 256行,则需要调用下面的代码解除对 256行的限制

 // 解除对256行的限制
        while(pModel->canFetchMore())
        {
            pModel->fetchMore();
        }

7、关闭数据库

 // 3、文件存在,判断是否打开
    bool isOpen         = sqliteDatabase.isOpen();
    // 3.1 若没有打开
    if (false           == isOpen)
    {
#ifdef QT_DEBUG
        qDebug() << "数据库没有打开";
        retVal          = 0;
        return retVal;
#endif
    }
    // 3.2 打开了数据库,再关闭
    else
    {
        sqliteDatabase.close();
#ifdef QT_DEBUG
        qDebug() << "数据库已经打开,现在已经关了";
#endif
    }

    // 4、移除数据库连接
    QSqlDatabase::removeDatabase("QSQLITE");

////////////////////////////////////////////////////////////////////////////////////

下面的增删改 都是需要设置 QSqlTableModel 为 手动提交,代码如下

 // 设置手动提交
        pModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

8、添加

 // 1、获取当前选择行
    int curTabIndex                 = tabWidget->currentIndex();
    // 1.1 若没有选择行
    if (-1                          == curTabIndex)
    {

        QMessageBox::information(this, tr("tip"), tr("err, threre is no tab"));
        return;
    }

    // 2、获取当前选择行
    int rowIndex                    = tableViewArr[curTabIndex]->currentIndex().row();

    // 添加到哪一行
    int addRowIndex                 = 0;
    // 2.1 若没有选择行
    if (-1                          == rowIndex)
    {
        // 默认设置选择当前tableview的最后一行
        addRowIndex                 = tableViewArr[curTabIndex]->model()->rowCount();
    }
    // 2.2 若已经选择行
    else
    {
        // 添加到选择行的下一行
        addRowIndex                 = rowIndex + 1;
    }

    // 3、向sqltableModel中添加一行
    bool isAdd                      = sqlTableModel[curTabIndex]->insertRow(addRowIndex);
    // 3.1 若添加失败
    if (false                       == isAdd)
    {
        // 提示添加失败
        QMessageBox::warning(this, tr("tip"), tr("add failed, add a new row failed"));
        return;
    }

9、删除

// 1、得到当前选择的是哪一个tab
    int curTabIndex                 = tabWidget->currentIndex();
    if (-1                          == curTabIndex)
    {
        QMessageBox::warning(this, tr("warning"), tr("delete failed, because there is no tab"));
        return;
    }

    // 2、得到选中的行
    QItemSelectionModel *selections = tableViewArr[curTabIndex]->selectionModel();
    QModelIndexList selected        = selections->selectedIndexes();

    // 保存选择了哪些行
    QVector  delRowsArr;
    delRowsArr.clear();
    foreach (QModelIndex index, selected)
    {
        int rowIndex    = index.row();
#ifdef QT_DEBUG
        qDebug() << "当前行为 = " << rowIndex + 1;
#endif
        int size = delRowsArr.count();
        bool isExist        = false;
        for (int i = 0; i < size; i++)
        {
            // 若删除行已经存在
            if (delRowsArr[i]   == rowIndex)
            {
                isExist         = true;
                break;
            }
        }

        // 若已经存在,则不加入到删除数组中
        if (true                == isExist)
        {

        }
        else
        {
            delRowsArr.append(rowIndex);
        }

    }

    const int delArrCount           = delRowsArr.count();
    if (0                           == delArrCount)
    {
        QMessageBox::warning(this, tr("warning"), tr("delete failed, because there is no selected row"));
        return ;
    }

    // 3、确认是否删除
    int isOk                        = QMessageBox::warning(this, tr("warning"), tr("Are u sure del the selected row"), QMessageBox::Yes,    QMessageBox::No);
    if (QMessageBox::No             == isOk)
    {
        return;
    }

#ifdef QT_DEBUG
    qDebug() << "删除的行总数 = " << delArrCount;
#endif
    for (int i; i < delArrCount; i++)
    {
        sqlTableModel[curTabIndex]->removeRow(delRowsArr[i]);
    }

    // 4、提交
    bool isSuccess                  =  sqlTableModel[curTabIndex]->submitAll();//tableViewArr[curTabIndex]->model()->submit();
    if (false                       == isSuccess)
    {
        // 删除提交失败,则回滚
        sqlTableModel[curTabIndex]->revertAll();

        // 提示删除失败
        QMessageBox::warning(this, tr("warning"), tr("delete falied , submit failed"));
        return;
    }

#ifdef QT_DEBUG
    qDebug() << "delete success , submit success";
#endif

10、修改

QTableview,双击单元格, 可以修改数据, 若同时修改数据库,需要手动提交修改结果

。。

11、提交

// 1、获取当前选择的是哪一个tab
    int curTabIndex                 = tabWidget->currentIndex();

    // 若没有tab
    if (-1                          == curTabIndex)
    {
        QMessageBox::warning(this, tr("tip"), tr("err,  there is no tab"));
        return;
    }

    // 2、提交当前tab下的新增记录
    int isSubmitSuccess             = sqlTableModel[curTabIndex]->submitAll();
    // 2.1 提交失败
    if (false                       == isSubmitSuccess)
    {
        QMessageBox::warning(this, tr("submit"), tr("the behavior of submit has failed, Please  Check new line's Id"));
        return;
    }

---------------------------------------------------------------------------------------

文章最前面的图片中,设置的有点击工具栏按钮实现 选择 QTableView的上一个和下一个, 还有最前 和最后

---------------------------------------------------------------------------------------

12、最前

 // 1、获取当前选择的是哪一个tab
    int curTabIndex         = tabWidget->currentIndex();
    // 若没有tab
    if (-1                  == curTabIndex)
    {
        QMessageBox::warning(this, tr("warning"), tr("err, there is no tab"));
        return;
    }

    // 2、设置选中第一行
    int tableViewCount      = tableViewArr[curTabIndex]->model()->rowCount();
    if (0 < tableViewCount)
    {
        tableViewArr[curTabIndex]->selectRow(0);
    }

13、上一个

// 1、获取当前选择的是哪一个tab
    int curTabIndex         = tabWidget->currentIndex();
    // 若没有tab
    if (-1                  == curTabIndex)
    {
        QMessageBox::warning(this, tr("warning"), tr("err, there is no tab"));
        return;
    }

    // 2、获取当前行
    int curRowIndex         = tableViewArr[curTabIndex]->currentIndex().row();
#ifdef QT_DEBUG
    qDebug() << "上一个 , 当前行索引 = "  << curRowIndex;
#endif //QT_DEBUG

    // 若没有选择,则默认选择第一个
    if (-1                  == curRowIndex)
    {
        curRowIndex         = 0;
    }
    else
    {
        if  (0 < curRowIndex)
        {
            curRowIndex         -= 1;
        }

    }
    tableViewArr[curTabIndex]->selectRow(curRowIndex);

14、下一个

// 1、获取当前选择的是哪一个tab
    int curTabIndex         = tabWidget->currentIndex();
    // 若没有tab
    if (-1                  == curTabIndex)
    {
        QMessageBox::warning(this, tr("warning"), tr("err, there is no tab"));
        return;
    }

    // 2、获取当前行
    int curRowIndex         = tableViewArr[curTabIndex]->currentIndex().row();
    int totalCount          = tableViewArr[curTabIndex]->model()->rowCount();

    // 若没有选择行
    if (-1                  == curRowIndex)
    {
        curRowIndex         = 0;
    }
    else
    {
#ifdef QT_DEBUG
        qDebug() << "下一个,当前行 = " << curRowIndex << "    总行数 = " << totalCount;
#endif
        if  (curRowIndex < totalCount - 1)
        {
            curRowIndex         += 1;
        }
    }

#ifdef QT_DEBUG
    qDebug() << "下一个, +1 后 = " << curRowIndex;
#endif
    tableViewArr[curTabIndex]->selectRow(curRowIndex);

15、最后

// 1、获取当前选择的是哪一个tab
    int curTabIndex         = tabWidget->currentIndex();
    // 若没有tab
    if (-1                  == curTabIndex)
    {
        QMessageBox::warning(this, tr("warning"), tr("err, there is no tab"));
        return;
    }

    // 2、设置选中最后一行
    int totalCount          = tableViewArr[curTabIndex]->model()->rowCount();
    tableViewArr[curTabIndex]->selectRow(totalCount - 1);

---------------------------------------------------------------------------------------

下面的代码是关于 查找 模块的

---------------------------------------------------------------------------------------

Qt5之使用sqlite3数据库_第2张图片


16、查找实现

这里, 支持 模糊查找

QString str = keyStr;
#ifdef QT_DEBUG
    qDebug() << "输入框内容 = " << str;
#endif

    // 1、获取当前选择的是哪一个tab
    int curTabIndex = tabWidget->currentIndex();

    // 若没有tab页
    if (-1          == curTabIndex)
    {
        return;
    }

    // 2、取从哪一列开始查找
    QString columnName  = columnNameStr;

    // 3、若输入框没有输入
    // 输入框有内容,则应该按照选择来筛选
     QString filterStr("");
    filterStr = QString(tr("%1 like '%%2%%'")).arg(columnName).arg(str);
    // 根据条件查找
    sqlTableModel[curTabIndex]->setFilter(filterStr);

    // 4、刷新显示界面数据
    sqlTableModel[curTabIndex]->select();

模糊查找关键代码如下,使用的是QSqlTableModel的Filter函数

  QString filterStr("");
    filterStr = QString(tr("%1 like '%%2%%'")).arg(columnName).arg(str);
    // 根据条件查找
    sqlTableModel[curTabIndex]->setFilter(filterStr);

------------------------------------------------------------------------------

17、排序

Qt5之使用sqlite3数据库_第3张图片

这里支持升序和降序

当选择的排序方式发生变化后,执行下面的代码执行排序

 // 0、哪一个tab被选中
    int curTabIndex = tabWidget->currentIndex();
    if (-1          == curTabIndex)
    {
        return;
    }


    QString curStr  = text;

    // 1、每一项都是 列名 + 空格 + 排序方式
    QString columnName("");
    QString sortType("");

    int spacePos    = curStr.indexOf(" ");
    // 2、列名
    columnName      = curStr.mid(0, spacePos);

#ifdef QT_DEBUG
//    qDebug() << "列名= " << columnName;
#endif
    // 3、排序方式
    sortType        = curStr.mid(spacePos + 1, curStr.length());
#ifdef QT_DEBUG
//    qDebug() << "排序方式= " << sortType;
#endif

    // 4、按照选择的排序方式排序
    // 4.1 按照哪一列排序
    int sortIndex = 0;
    for (int i = 0; i < curTableViewColumnNameList.count(); i++)
    {
        // 若相等
        if (columnName  == curTableViewColumnNameList.at(i))
        {
            break;
        }

        sortIndex       += 1;
    }


    // 升序还是降序
    // 0 - 升序, 1 降序
    if ("ASC"           == sortType)
    {
        // 5、排序
        sqlTableModel[curTabIndex]->setSort(sortIndex, Qt::AscendingOrder);
    }
    else if ("DESC"     == sortType)
    {
        // 5、排序
        sqlTableModel[curTabIndex]->setSort(sortIndex, Qt::DescendingOrder);
    }


    // 查询现实
    sqlTableModel[curTabIndex]->select();





你可能感兴趣的:(Qt5)