• QT中sqlite的使用


    1. 创建连接

    1. QSqlDatabase  db1=QSqlDatabase::addDatabase("QSQLITE","connect1");
    2. db1.setDatabaseName("memory.db");

    1.1 db1是数据库对象,其中打开数据库,查找数据库时要用到这个对象。这个对象只能在创建的线程调用;

    1.2 connect1是可选填参数,表示的是连接名。如果不指定连接名,则使用默认的qt_sql_default_connection名字。连接名是一个QString,没有说明限制多长的字符串,实测127个字符也没问题。一个数据库可以有多个连接名,不同连接名可以在不同线程中同时操作。

    • 1.3 memory.db就是数据库的名字。
    • 创建连接后该连接就拥有相应数据库的功能了。

    2. 往连接里创建表格

    QSqlQuery::exec(“create table student(id int““primary key,name varcher(40)”);

    括号里面的字符串是SQLite的命令语句,通过该函数几乎可以运行SQLite的所有命令。但具体用法不是这样,正确的用法如下:

    1. // QSqlQuery query1;//这里没有指定db1,则使用默认连接
    2. QSqlQuery query1(db1); // 这里指定使用连接db1。如果没有创建相应的连接,则会执行错误。
    3. bool ret = query1.exec(“create table student(id int““primary key,name varcher(40)”);
    4. if(ret == false){// 数据库操作失败
    5.     qDebug()<< query.lastError(); //打印错误信息
    6. }


    提示: 使用指定连接的好处有两:

    • 一、当一个程序要操作多个数据库时,指定的连接可以对应指定的数据库。
    • 二、当一个程序要多线程操作一个数据库时,就要创建多个连接,不同的线程要用不同的连接。执行QSqlQuery 就要指定数据库连接。(尽量不要多线程操作数据库)

    2.1 创建例程运行

    创建表格后,运行程序,工程目录下会生成一个.db文件,就是数据库文件。该文件包含了表格内容,需要用相应工具软件打开,如:Navicat(可惜这个工具是收费的),直接百度搜sqlite工具也能找到很多免费的好用工具。同时,里面的数据也可以用该软件导出成其他文本格式。

    3. QSqlDatabase类简介

    一个数据库可以创建多个连接。

    连接的作用就是在qt中操作数据库。

    4. QSqlQuery类使用简介

    接口API功能描述
    exec(const QString &query)运行数据库命令,输入字符串。
    exec("select * from books"查询当前连接的books表格所有字段的记录;只有执行了这句,下面的语句才能正常运行。
    value(int) 获取当前索引下记录中某个字段的值,输入参数表示几号字段。
    int size()

    获取当前连接下,正在查询的表格的记录数(行数),并不是所有数据库都支持,SQLite就不支持。可以使用下面方法查询一下,

    QSqlDatabase ::hasFeature(QSqlDriver::QuerySize);

    如果要查询sqlite的行数,可以使用

    QString("SELECT count(*) from %1;").arg(tableName);

    last()

    将当前连接正在查询的表格定位到最后一条记录,当用其他函数取值时取的就是最后一条记录的值。

    当数据量超过10万条时,此函数的耗时会明显增多。

    at() 

    返回当前跟踪的表格的索引index,类似于数组的下标。字段里的id与这个不一样,字段的值都是自己输入到表格,字段名也可改为不叫id。

    seek(int)将当前跟踪定位到指定位置index。

    另外相关的类还有:

    QSqlRecord record():获取当前索引的记录,然后可以调用value(const QString &name)获取相应字段的值。调用field(int)可以定位字段。详情可翻看帮助手册。

    5. 往表格插入、删除、更新数据

    这里直接使用如下api来调用数据库命令即可。

    QSqlQuery::exec(const QString &query)

    数据库命令可以直接看数据库的命令手册。如下面这些命令:

    "select * from books"该句表示查找books表格中所有字段的记录。select是SQLite关键字, "select column1, column2 from books" 这样就是指定查两个字段的值。

    "insert into books (id,name) values(4,'The Little Prince')"从books表格尾部加一条记录。

    "insert into books (id,name) values(:id,:name)"使用名称占位符插入记录,这样就可以使用变量,可以同时插入多条记录。还有位置占位符形式,:id,:name会变成?,?,详情看QT的教程。

    使用示例如下:

    1. QSqlQuery.exec("select * from books");
    2. QSqlQuery.exec("select column1, column2 from books");

    5.1 列操作

    1. ALTER TABLE tableName ADD COLUMN newColumName BLOB #增加列
    2. ALTER TABLE tableName DROP COLUMN columName #删除列

    6. 注意

    6.1 多线程操作数据库可能引发程序崩溃。

    解决方法:增加互斥量操作数据库。

    首先qt中创建数据库连接返回的对象只能在当前线程使用,但是连接名可以多线程使用。如下:

    db1对象只能在当前线程使用;

    connect1可以在多个线程使用;

    1. QSqlDatabase  db1=QSqlDatabase::addDatabase("QSQLITE","connect1");
    2. db1.setDatabaseName("memory.db");

    然后,多线程使用sqlite时,存在资源竞争问题。

    默认情况下,在sqlite内部有5中锁状态,某个线程在访问数据库的时候(读或写),都会给数据库上锁,等该线程释放锁后,其他线程才能访问数据库。

    推荐阅读《SQLite权威指南》,有中文版翻译。

    6.2 同一个线程开了数据库要关闭

    如:错误代码示例

    1. // 错误代码示例
    2. QSqlDatabase _db;
    3. _db = QSqlDatabase::database(name);
    4. _db.open();
    5. QSqlQuery query(_db);
    6. query.exec("select * from tableName");
    7. query.next();
    8. ...
    9. {
    10. QSqlDatabase _db;
    11. _db = QSqlDatabase::database(name2);
    12. _db.open();
    13. // ...查询,插入等等操作;
    14. _db.close();
    15. }
    16. _db.close();

    这样操作会导致数据库被锁。

  • 相关阅读:
    贪心一【深基12.例1】部分背包问题详解
    requests爬虫详解
    推荐一本AI+医疗书:《机器学习和深度学习基础以及医学应用》,附21篇精选综述
    UE4动作游戏实例RPG Action解析二:GAS系统播放武器绑定的技能,以及GE效果
    前后端数据接口协作提效实践
    MobPush for Uni-app
    QT Day2
    docker 启动简单的开发环境(mysql, redis, etcd)
    java基于微信小程序的劳务知识分享系统 uniapp 小程序
    TypeScript 之 Interface
  • 原文地址:https://blog.csdn.net/qq_25355591/article/details/127933670