zoukankan      html  css  js  c++  java
  • Qt 操作SQLite数据库

    项目中通常需要采用各种数据库(如 Qracle、SQL Server、MySQL等)来实现对数据的存储、查询等功能。下面讲解如何在 Qt 中操作 SQlite 数据库。


    一、SQLite 介绍

    Sqlite 数据库作为 Qt 项目开发中经常使用的一个轻量级的数据库,可以说是兼容性相对比较好的数据库之一(Sqlite就像Qt的亲儿子,如同微软兼容Access数据库一样)。Qt5 以上版本可以直接使用(Qt自带驱动),是一个轻量级的数据库,概况起来具有以下优点:

    • SQLite 的设计目的是嵌入式 SQL 数据库引擎,它基于纯C语言代码,已经应用于非常广泛的领域内。
    • SQLite 在需要长时间存储时可以直接读取硬盘上的数据文件(.db),在无须长时间存储时也可以将整个数据库置于内存中,两者均不需要额外的服务器端进程,即 SQLite 是无须独立运行的数据库引擎。
    • 源代码开源,你可以用于任何用途,包括出售它。
    • 零配置 – 无需安装和管理配置。
    • 不需要配置,不需要安装,也不需要管理员。
    • 同一个数据文件可以在不同机器上使用,可以在不同字节序的机器间自由共享。
    • 支持多种开发语言,C, C++, PHP, Perl, Java, C#,Python, Ruby等。

    二、用法

    2.1 准备

    1、引入SQL模块
    在Qt项目文件(.pro文件)中,加入SQL模块:

    QT += sql
    

    2、引用头文件

    在需要使用SQL的类定义中,引用相关头文件。例如:

    #include <QSqlDatabase>
    #include <QSqlError>
    #include <QSqlQuery>
    

    2.2 使用

    1、建立数据库

    QSqlDatabase database;
    
    if (QSqlDatabase::contains("qt_sql_default_connection"))
    {
        database = QSqlDatabase::database("qt_sql_default_connection");
    }
    else
    {
        // 建立和SQlite数据库的连接
        database = QSqlDatabase::addDatabase("QSQLITE");
        // 设置数据库文件的名字
        database.setDatabaseName("MyDataBase.db");
    }
    
    • 第一行中,建立了一个 QSqlDatabase 对象,后续的操作要使用这个对象。

    • if 语句用来检查指定的连接(connection)是否存在。这里指定的连接名称(connection name)是qt_sql_default_connection,这是 Qt 默认连接名称。实际使用时,这个名称可以任意取。如果判断此连接已经存在,那么 QSqlDatabase::contains() 函数返回 true。此时,进入第一个分支,QSqlDatabase::database() 返回这个连接。

    • 如果这个连接不存在,则进入else分支,需要创建连接,并添加数据库。在else分支第一行,addDatabase()的参数QSQLITE是SQLite对应的驱动名,不能改。而且需要注意的是,addDatabase()的第二个参数被省略了,第二个参数的默认参数就是上面提到的Qt默认连接名称 qt_sql_default_connection。如果需要使用自定义的连接名称(如果程序需要处理多个数据库文件的话就会这样),则应该加入第二个参数,例如:

      database = QSqlDatabase::addDatabase("QSQLITE", "my_sql_connection);
      

      这个时候,如果在另一个地方需要判断my_sql_connection连接是否存在,就应该使用 if (QSqlDatabase::contains("my_sql_connection"))

    • else 分支第二行中,setDatabaseName() 的参数是数据库文件名。如果这个数据库不存在,则会在后续操作时自动创建;如果已经存在,则后续的操作会在已有的数据库上进行。


    2、打开数据库

    使用 open() 打开数据库,并判断是否成功。注意,在第一步检查连接是否存在时,如果连接存在,则在返回这个连接的时候,会默认将数据库打开。

    if (!database.open())
    {
        qDebug() << "Error: Failed to connect database." << database.lastError();
    }
    else
    {
        // do something
    }
    

    如果打开数据库成功,则进入else分支。对数据库的操作都需要在else分支中进行。


    3、关闭数据库

    数据库操作完成后,最好关闭。

    database.close();
    

    4、操作数据库

    对数据库进行操作需要用到 QSqlQuery 类,操作前必须定义一个对象。下面举例说明操作方法。操作需要使用 SQL 语句,本文中的几个例子会使用几个常用的语句,关于 SQL 语句的具体信息可以参考我的另一篇博客:[SQL必知必会] 读书笔记


    例1:创建表格

    创建一个名为student的表格,表格包含三列,第一列是id,第二列是名字,第三列是年龄。

    // 用于执行sql语句的对象
    QSqlQuery sqlQuery;
    // 构建创建数据库的sql语句字符串
    QString createSql = QString("CREATE TABLE student (
                              id INT PRIMARY KEY NOT NULL,
                              name TEXT NOT NULL,
                              age INT NOT NULL)");
    sqlQuery.prepare(createSql);
    // 执行sql语句
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();
    }
    else
    {     qDebug() << "Table created!";
    }
    
    • 第一行定义一个 QSqlQuery 对象。

    • 第二行是一个 QString,其中的内容是 SQLite 语句。对数据库的操作,都是用 SQLite 的语句完成的,把这些指令以 QString 类型,通过 prepare 函数,保存在 QSqlQuery 对象中。也可将指令,以 QString 形式直接写在 exec() 函数的参数中,例如:

      sql_query.exec("CREATE TABLE student (ID INT PRIMARY KEY NOT NULL, ...)");
      
    • 如果 sql_query.exec() 执行成功,则创建表格成功。


    例2:插入单行数据

    在刚才创建的表格中,插入单行数据。

    // 方法一:使用 bindValue 函数插入单行数据
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO student VALUES(:id,:name,:age)");
    sqlQuery.bindValue(":id", max_id + 1);
    sqlQuery.bindValue(":name", "Wang");
    sqlQuery.bindValue(":age", 25);
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
    }
    else
    {
    	// do something    
    }
    
    // 方法二:使用 addBindValue 函数插入单行数据
    QSqlQuery sqlQuery;
    sqlQuery.prepare("INSERT INTO student VALUES(?, ?, ?)");
    sqlQuery.addBindValue(max_id + 1);
    sqlQuery.addBindValue("Wang");
    sqlQuery.addBindValue(25);
    if(!sqlQuery.exec())
    {
        qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
    }
    else
    {
    	// do something    
    }
    
    // 方法三:直接写出完整语句
    if(!sql_query.exec("INSERT INTO student VALUES(3, "Li", 23)"))
    {
        qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
    }
    else
    {
    	// do something 
    }
    

    例3:查询全部数据

    QSqlQuery sqlQuery;
    sqlQuery.exec("SELECT * FROM student");
    if(!sqlQuery.exec())
    {
    	qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
    }
    else
    {
    	while(sqlQuery.next())
    	{
    		int id = sqlQuery.value(0).toInt();
    		QString name = sqlQuery.value(1).toString();
    		int age = sqlQuery.value(2).toInt();
    		qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
    	}
    }
    

    例4:更新数据(修改数据)

    QSqlQuery sqlQuery;
    sqlQuery.prepare("UPDATE student SET name=?,age=? WHERE id=?");
    sqlQuery.addBindValue(name);
    sqlQuery.addBindValue(age);
    sqlQuery.addBindValue(id);
    if(!sqlQuery.exec())
    {
        qDebug() << sqlQuery.lastError();
    }
    else
    {
        qDebug() << "updated data success!";
    }
    

    三、完整示例程序

    上面只是列举了几个常用的SQL语句例子,下面贴出一个完整示例程序:

    SqliteOperator.h

    #ifndef SQLITEOPERATOR_H
    #define SQLITEOPERATOR_H
    
    #include <QSqlDatabase>
    #include <QSqlQuery>
    #include <QSqlError>
    #include <QDebug>
    
    typedef struct
    {
        int id;
        QString name;
        int age;
    }w2dba;
    
    class SqliteOperator
    {
    public:
        SqliteOperator();
    
        // 打开数据库
        bool openDb(void);
        // 创建数据表
        void createTable(void);
        // 判断数据表是否存在
        bool isTableExist(QString& tableName);
        // 查询全部数据
        void queryTable();
        // 插入数据
        void singleInsertData(w2dba &singleData); // 插入单条数据
        void moreInsertData(QList<w2dba> &moreData); // 插入多条数据
        // 修改数据
        void modifyData(int id, QString name, int age);
        // 删除数据
        void deleteData(int id);
        //删除数据表
        void deleteTable(QString& tableName);
        // 关闭数据库
        void closeDb(void);
    
    private:
        QSqlDatabase database;// 用于建立和数据库的连接
    };
    
    #endif //  SQLITEOPERATOR_H
    

    SqliteOperator.cpp

    #include "sqliteoperator.h"
    
    // 构造函数中初始化数据库对象,并建立数据库
    SqliteOperator::SqliteOperator()
    {
        if (QSqlDatabase::contains("qt_sql_default_connection"))
        {
            database = QSqlDatabase::database("qt_sql_default_connection");
        }
        else
        {
            // 建立和SQlite数据库的连接
            database = QSqlDatabase::addDatabase("QSQLITE");
            // 设置数据库文件的名字
            database.setDatabaseName("MyDataBase.db");
        }
    }
    
    // 打开数据库
    bool SqliteOperator::openDb()
    {
        if (!database.open())
        {
            qDebug() << "Error: Failed to connect database." << database.lastError();
        }
        else
        {
            // do something
        }
    
        return true;
    }
    
    // 创建数据表
    void SqliteOperator::createTable()
    {
        // 用于执行sql语句的对象
        QSqlQuery sqlQuery;
        // 构建创建数据库的sql语句字符串
        QString createSql = QString("CREATE TABLE student (
                              id INT PRIMARY KEY NOT NULL,
                              name TEXT NOT NULL,
                              age INT NOT NULL)");
        sqlQuery.prepare(createSql);
        // 执行sql语句
        if(!sqlQuery.exec())
        {
            qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();
        }
        else
        {
            qDebug() << "Table created!";
        }
    }
    
    // 判断数据库中某个数据表是否存在
    bool SqliteOperator::isTableExist(QString& tableName)
    {
        QSqlDatabase database = QSqlDatabase::database();
        if(database.tables().contains(tableName))
        {
            return true;
        }
    
        return false;
    }
    
    // 查询全部数据
    void SqliteOperator::queryTable()
    {
        QSqlQuery sqlQuery;
        sqlQuery.exec("SELECT * FROM student");
        if(!sqlQuery.exec())
        {
            qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
        }
        else
        {
            while(sqlQuery.next())
            {
                int id = sqlQuery.value(0).toInt();
                QString name = sqlQuery.value(1).toString();
                int age = sqlQuery.value(2).toInt();
                qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
            }
        }
    }
    
    // 插入单条数据
    void SqliteOperator::singleInsertData(w2dba &singledb)
    {
        QSqlQuery sqlQuery;
        sqlQuery.prepare("INSERT INTO student VALUES(:id,:name,:age)");
        sqlQuery.bindValue(":id", singledb.id);
        sqlQuery.bindValue(":name", singledb.name);
        sqlQuery.bindValue(":age", singledb.age);
        if(!sqlQuery.exec())
        {
            qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
        }
        else
        {
            // do something
        }
    }
    
    // 插入多条数据
    void SqliteOperator::moreInsertData(QList<w2dba>& moredb)
    {
        // 进行多个数据的插入时,可以利用绑定进行批处理
        QSqlQuery sqlQuery;
        sqlQuery.prepare("INSERT INTO student VALUES(?,?,?)");
        QVariantList idList,nameList,ageList;
        for(int i=0; i< moredb.size(); i++)
        {
            idList <<  moredb.at(i).id;
            nameList << moredb.at(i).name;
            ageList << moredb.at(i).age;
        }
        sqlQuery.addBindValue(idList);
        sqlQuery.addBindValue(nameList);
        sqlQuery.addBindValue(ageList);
    
        if (!sqlQuery.execBatch()) // 进行批处理,如果出错就输出错误
        {
            qDebug() << sqlQuery.lastError();
        }
    }
    
    // 修改数据
    void SqliteOperator::modifyData(int id, QString name, int age)
    {
        QSqlQuery sqlQuery;
        sqlQuery.prepare("UPDATE student SET name=?,age=? WHERE id=?");
        sqlQuery.addBindValue(name);
        sqlQuery.addBindValue(age);
        sqlQuery.addBindValue(id);
        if(!sqlQuery.exec())
        {
            qDebug() << sqlQuery.lastError();
        }
        else
        {
            qDebug() << "updated data success!";
        }
    }
    
    // 删除数据
    void SqliteOperator::deleteData(int id)
    {
        QSqlQuery sqlQuery;
    
        sqlQuery.exec(QString("DELETE FROM student WHERE id = %1").arg(id));
        if(!sqlQuery.exec())
        {
            qDebug()<<sqlQuery.lastError();
        }
        else
        {
            qDebug()<<"deleted data success!";
        }
    }
    
    //删除数据表
    void SqliteOperator::deleteTable(QString& tableName)
    {
        QSqlQuery sqlQuery;
    
        sqlQuery.exec(QString("DROP TABLE %1").arg(tableName));
        if(sqlQuery.exec())
        {
            qDebug() << sqlQuery.lastError();
        }
        else
        {
            qDebug() << "deleted table success";
        }
    }
    
    void SqliteOperator::closeDb(void)
    {
        database.close();
    }
    

    main.cpp

    #include <QCoreApplication>
    #include "sqliteoperator.h"
    #include <QString>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        //创建并打开SQLite数据库
        SqliteOperator sqlTest;
        sqlTest.openDb();
    
        // 创建数据表
        sqlTest.createTable();
    
        // 判断数据表是否存在
        QString str1 = QString("student");
        qDebug() << "isTabelExist:" <<sqlTest.isTableExist(str1);
    
        // 插入单条数据
        w2dba w2dbaTest1 = {1, "zhangSan", 24};
        w2dba w2dbaTest2 = {2, "lisi", 28};
        sqlTest.singleInsertData(w2dbaTest1);
        sqlTest.singleInsertData(w2dbaTest2);
    
        // 插入多条数据
        QList<w2dba> list;
        w2dba w2dbaTest3 = {3, "liwu", 26};
        w2dba w2dbaTest4 = {4, "niuer", 27};
        list.append(w2dbaTest3);
        list.append(w2dbaTest4);
        sqlTest.moreInsertData(list);
        // 查询全部数据
        sqlTest.queryTable();
        qDebug() << endl;
    
        // 修改数据
        sqlTest.modifyData(2, "modify", 10);
        // 查询全部数据
        sqlTest.queryTable();
        qDebug() << endl;
    
        // 删除数据
        sqlTest.deleteData(2);
        // 查询全部数据
        sqlTest.queryTable();
        qDebug() << endl;
    
        // 删除数据表
        QString str2 = QString("student");
        sqlTest.deleteTable(str2);
    
        //关闭数据库
        sqlTest.closeDb();
    
        return a.exec();
    }
    

    运行结果如下:

    Table created!
    isTabelExist: true
    "id:1    name:zhangSan    age:24"
    "id:2    name:lisi    age:28"
    "id:3    name:liwu    age:26"
    "id:4    name:niuer    age:27"
    
    updated data success!
    "id:1    name:zhangSan    age:24"
    "id:2    name:modify    age:10"
    "id:3    name:liwu    age:26"
    "id:4    name:niuer    age:27"
    
    deleted data success!
    "id:1    name:zhangSan    age:24"
    "id:3    name:liwu    age:26"
    "id:4    name:niuer    age:27"
    
    deleted table success
    

    参考:

    Qt下Sqlite数据库的操作(1)

    QT5中使用SQLite

    在Qt中使用SQLite数据库


  • 相关阅读:
    【剑指Offer】21、栈的压入、弹出序列
    【剑指Offer】20、包含min函数的栈
    【剑指Offer】19、顺时针打印矩阵
    【Shell编程】Shell基本语法
    【Shell编程】Shell程序设计
    linux 大中括号变量解读
    Python 二进制,十进制,十六进制转换
    Python3.x和Python2.x的区别
    python通过SSH登陆linux并操作
    PEP8特性
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/11364071.html
Copyright © 2011-2022 走看看