QT 数据库

sqlite

SQLITE功能简约,小型化,追求最大磁盘效率,支持跨平台,不需要服务器,在本地的。

数据库操作基本的功能QT里面都有,可视化软件也很小。有支持关系模式的model。

In-memory database(IMDB),即内存数据库,是一种依赖于主存作为数据存储介质的一种数据库管理系统。相比传统的基于磁盘的数据库管理系统,IMDB速度快得多。

MYSQL

MySQL的安装与配置——详细教程 - Winton-H - 博客园为安装教程。

mysql配置比较麻烦,折腾了一天才配置好。第一个是不要用太高版本的mysql,用mysql8.0 是配置不了的,配置很多遍都配置不了。用mysql5.7.29一次就OK了。配置的方法参考【Qt】Qt5.12编译MySQl5.7驱动(亲自测试成功) - 沧海一笑_DJ - 博客园。第二个是mysql的位数要和QT编译器位数一致,编译器是32位的,mysql就是32位的,编译器是64位的,mysql必须是64位的。

MYSQL使用.bat一键安装

因为软件在部署的时候,往往都不是程序开发者本人去部署,所以需要使用一个便捷的方法,代替一个个cmd命令,使得他人在安装部署的时候简便快捷。参考此篇文章。Bat批处理命令实现一键安装mysql环境

数据库的迁移

使用HeidSQL可以直接把数据库迁移,使用SQL方式。至少在数据库数量小的时候特别有用。

注意事项

1.mysql只能连接创建好的数据库和使用已经创建好的表,目前没有找到打开数据库的时候创建的方法,然后创建的数据库在数据库安装的文件夹下面,不能移动。在打开数据后,还要执行"use +数据库名",才能执行sql语句。

不过可以使用一些技巧来处理,根据mysql的特性,先使用sys数据库进行连接,然后再根据需求创建数据库,后执行"use 数据库名",就可以执行一系列sql操作了。mysql的字符要用"";插入中文参考Incorrect string value: '\\xF0\\x9F\\x93\\x9E 1...' for column 'nickname' at row 1" 报错解决办法_weixin_42489971的博客-CSDN博客

2.mysql开启事务不能直接使用QT的函数transaction() commit(),而是使用query.exec("START TRANSACTION;")和query.exec("commit;")

3.Mysql的sql语句和sqlite的通用,数据类型可能有所不同,不过Mysql的默认编码不是utf8,所以会导致QT执行sql时执行不了(sql带中文的时候)。转码参考VS2013 Qt5 Mysql中文编码问题 - findumars - 博客园,windows下Qt访问mysql中文名数据库_joyopirate的博客-CSDN博客

4.多线程使用MySQL,同时一个连接建立多个查询,参考以下两篇文章,目前其它方法都不行。

https://blog.csdn.net/qq_43445867/article/details/125665961

https://blog.csdn.net/qq_43445867/article/details/125665961

以下是QT数据库的类的用法

QSqlDatabase

    QSqlDatabase类表示到数据库的连接。QSqlDatabase类提供了通过连接访问数据库的接口。QSqlDatabase的一个实例表示连接。该连接通过受支持的数据库驱动程序之一提供对数据库的访问,该驱动程序派生自QSqlDriver。或者,您可以从QSqlDriver派生您自己的数据库驱动程序。有关更多信息,请参见如何编写自己的数据库驱动程序。创建一个连接(例如。通过调用一个静态addDatabase()函数,在该函数中指定要使用的驱动程序或驱动程序类型(即,你要访问什么样的数据库?)和一个连接名。一个连接通过它自己的名字而不是它所连接的数据库的名字被知道。可以有多个到一个数据库的连接。QSqlDatabase还支持默认连接的概念,即未命名连接。要创建默认连接,在调用addDatabase()时不要传递连接名参数。随后,当您调用任何接受连接名参数的静态成员函数时,如果没有传递连接名参数,则假定为默认连接。下面的代码片段展示了如何创建和打开到PostgreSQL数据库的默认连接。

    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    db.setHostName("acidalia");
    db.setDatabaseName("customdb");
    db.setUserName("mojito");
    db.setPassword("J0a1m8");
    bool ok = db.open();

QSqlQuery 

    QSqlQuery类提供了一种执行和操作SQL语句的方法。QSqlQuery封装了在QSqlDatabase上执行的SQL查询中创建、导航和检索数据所涉及的功能。它可以用来执行DML(数据操作语言)语句,比如SELECT、INSERT、UPDATE和DELETE,也可以用来执行DDL(数据定义语言)语句,比如CREATE TABLE。它还可以用来执行非标准SQL的特定于数据库的命令(例如,SET DATESTYLE=ISO for PostgreSQL)。

    成功执行的SQL语句将查询的状态设置为active,以便isActive()返回true。否则,查询的状态设置为inactive。在这两种情况下,当执行一个新的SQL语句时,查询被定位在一个无效的记录上。在检索值之前,必须将活动查询导航到有效的记录(以便isValid()返回true)。

     对于某些数据库,如果在调用commit()或rollback()时存在一个活动查询(即SELECT语句),则提交或回滚将失败。有关详细信息,请参见isActive()。

导航记录通过以下功能实现:
next() previous() first() last() seek()

     这些函数允许程序员向前、向后或任意地遍历查询返回的记录。如果只需要遍历结果(例如,通过使用next()),则可以使用setForwardOnly(),这将节省大量内存开销并提高某些数据库的性能。一旦活动查询定位在有效记录上,就可以使用value()检索数据。使用qvariant从SQL后端传输所有数据。

     要访问查询返回的数据,请使用value(int)。SELECT语句返回的数据中的每个字段都是通过传递该字段在语句中的位置(从0开始)来访问的。这使得使用SELECT *查询是不可取的,因为返回字段的顺序是不确定的。

     QSqlQuery支持预先准备的查询执行和将参数值绑定到占位符。有些数据库不支持这些特性,因此Qt模拟了所需的功能。例如,Oracle和ODBC驱动程序有适当的准备好的查询支持,Qt利用它;但是对于没有这种支持的数据库,Qt实现了特性本身,例如,在执行查询时用实际值替换占位符。使用numRowsAffected()查找非SELECT查询影响了多少行,使用size()查找SELECT检索了多少行。(这个特性用于插入、更新、删除很有用,避免写了一堆QString的SQL语句)占位符使用于插入、修改语句。

在创建QSqlQuery之前,必须加载SQL驱动程序并打开连接。此外,在查询存在时,连接必须保持打开状态;否则,QSqlQuery的行为是未定义的。

QSqlQuery不支持多个查询语句,使用多个select默认执行第一个。

QSqlRecord

封装了一条数据库记录。

QSqlRecord类封装了数据库记录的功能和特征(通常是数据库表或视图中的一行)。QSqlRecord支持添加和删除字段,以及设置和检索字段值。

QSqlQuery快速插入数据法

db.transaction();

query.prepare(...);   //只需要调用一次,调用多次就会慢

query.addBindValue(...);

db.commit();

//速度提升很多倍,使用QString直接插入比较耗时。

QSqlRelationalTableModel

QSqlRelationalTableModel类为单个数据库表提供了一个可编辑的数据模型,并且支持外键。使用构造函数时,不指定数据库连接,会自己使用默认的数据库连接,比如在内存中的数据库连接。fieldIndex()找到表中名字所在的属性列索引,setRelation()让指定的列成为由关系指定的外部索引

QSqlRelationalDelegate

QSqlRelationalDelegate类提供一个委托,用于显示和编辑来自QSqlRelationalTableModel的数据。可以定制化数据显示的方式(甚至可以画出来)和编辑方式(加QCombox等等)。

QDataWidgetMapper

QDataWidgetMapper类提供了数据模型部分到小部件之间的映射,可以将模型选中的数据映射到小部件来,随着模型选中的值改变和改变模型选中的值。

QSqlTableModel

QSqlTableModel类为单个数据库表提供了一个可编辑的数据模型。

使用构造函数时,不指定数据库连接,会自己使用默认的数据库连接,比如在内存中的数据库连接。QSqlTableModel是一个高级接口,用于从单个表读取和写入数据库记录。它构建在底层QSqlQuery之上,可以用来提供数据来查看类,比如QTableView。例如:   

QSqlTableModel *model = new QSqlTableModel(parentObject, database);
    model->setTable("employee");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

    QTableView *view = new QTableView;
    view->setModel(model);
    view->hideColumn(0); // don't show the ID
    view->show();

将模型操作所在的数据库表设置为tableName。不从表中选择数据,而是获取其字段信息。使用指定的筛选器和排序条件,使用通过setTable()设置的表中的数据填充模型,如果成功,则返回true;否则返回false。

QSqlQueryModel

QSqlQueryModel类为SQL结果集提供了一个只读数据模型。
QSqlQueryModel是一个高级接口,用于执行SQL语句和遍历结果集。它建立在较低级别的QSqlQuery之上,可以用来提供数据来查看类,比如QTableView。例如:

    QSqlQueryModel *model = new QSqlQueryModel;
    model->setQuery("SELECT name, salary FROM employee");
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

QSqlQueryModel也可以通过编程方式访问数据库,而不需要绑定到视图:

默认情况下,模型是只读的。要使它具有读写能力,必须子类化它并重新实现setData()和flags()。另一个选项是使用QSqlTableModel,它提供了基于单个数据库表的读写模型。

TIP

1.除了英文,创建表的时候有数字和中文都要加单引号。

2.可在SQLite Expert 验证语句是否正确。

3.SQL语句中出现中文乱码,加上QString::fromLocal8Bit(s)即可,和普通字符串一样。

4.频繁插入数据,1000次程序都很耗时,所以要一次性插入数据。

5.表在数据库中已经创建,再创建一次,不会新建一个表,向里面插入数据也不会覆盖里面的数据,而是在表后面追加。数据库如果在路径下创建了的话,创建连接的时候同样不会去覆盖它。

关系模式

sqllite设置主键,但是在可视化工具并没有显示什么,表与表之间的联系主要通过两个表都有相同的属性列,常用ID。

关系模式的使用在关系操作上。

QT 数据库_第1张图片

QT 数据库_第2张图片

索引

加索引是一种提升查找速率的有效办法,存储空间加一些,但是速度提升几十倍。看需要加哪种索引。

注意:对于定义为TEXTIMAGE的数据不应该创建索引。这些字段长度不固定,或许很长,或许为空。操作符BETWEEN、LIKE、OR不能用索引。Text不能用“=”运算符。索引名称不同表相同都不行,索引必须都不相同。

主键

主键不是联合主键的话,每一个记录的主键的值必须不相同,插入时如果值存在的话,会插入失败。联合主键中的其中一个属性可以重复,但是联合主键的值组合起来必须不能重复。体现了主键的唯一性,能唯一标识此表的属性。

Ubuntu下的mysql

ibqsqlmysql.so文件复制到lib文件夹下即可。但是大概QT5.10之后就没这个文件了。自己apt install去安装,版本也是QT5.9的。

高版本的QT Mysql驱动需要自己编译。参照https://blog.csdn.net/annjeff/article/details/105798351和Ubuntu安装mysql之后,编译找不到头文件 - 砚车干 - 博客园

常用语句

1.SELECT * FROM sqlite_master WHERE type='table';     获取数据库所有表。

QT的Demo

book 

图书示例展示了如何将Qt的SQL类与模型/视图框架一起使用,为存储在数据库中的信息创建丰富的用户界面。

这个案例用的是QSQLITE数据库,并且没有创建文件保存。tables()可以返回数据库中的包的名字。之后在表中创建有主键的表,sql语句为“create table books(id integer primary key, title varchar, author integer, genre integer, year integer, rating integer”,sql语句也可以用lastError()返回错误。

QSqlQuery调用prepare函数是为了准备执行一个SQL查询,有些数据库选择延迟准备查询,直到第一次执行它。在这种情况下,准备一个语法错误的查询会成功,但是每个连续的exec()都会失败。对于SQLite,查询字符串一次只能包含一条语句。如果给出了多个语句,则函数返回false。

下面的语句就是用了addBindValue插入数据,避免写了很长的QString。

QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate)
{
    q.addBindValue(name);
    q.addBindValue(birthdate);
    q.exec();
    return q.lastInsertId();
}

    if (!q.prepare(QLatin1String("insert into authors(name, birthdate) values(?, ?)")))
        return q.lastError();
    QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1));
    QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2));
    QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28));

"create table authors(id integer primary key, name varchar, birthdate date)"定义数据库的时候定义了id这个主键,每个数据库都定义。

这个例子建立了一个只在程序运行期间有效的数据库,但是这个数据库是一个全局的,在程序全局范围内均可用。

QCombox可以使用setModel设置模型,关联表的变量显示。

Cached Table Example

该示例包含一个类TableEditor,它是一个自定义对话框小部件,允许用户修改存储在数据库中的数据。

bool QSqlDatabase::commit()如果驱动程序支持事务并且已经启动了事务(),则将事务提交到数据库。如果操作成功,则返回true。否则返回false。

QSqlTableModel::revertAll()
恢复所有挂起的更改

Drill Down Example

这个例子涉及到动画的知识,只关注数据库知识即可。使用QSqlRelationalTableModel和QSqlRelation建立一个关系模式,然后QGraphicsScene根据这个模型添加图形项。InformationWindow这个窗口,使用QDataWidgetMapper关联窗口的控件,并支持回滚和提交功能。提交后,数据库的数据会改变,以及QGraphicsScene的图形项的图片会改变。

Master Detail Example

这个例子还用到XML的知识。XML是标准通用语言,可以考虑使用到一个软件的配置上。XML暂时不了解。

同样也是使用QSqlRelationalTableModel,建立关系,在albumView中显示。QSqlRecord类可以获取选中记录的信息,点击albumView的项,会在XML中查找相应的信息并在trackList中显示出来。这个例子的数据添加有点问题,等学习XML再看看。

querymodel

分别从直接使用的角度和继承的角度,介绍QSqlQueryModel的简单应用、可编辑应用,一般使用。直接应用只能显示不能修改,可编辑应用同时更新了数据库。一般使用可以定制化表格的一些显示。

relationaltablemodel

介绍QSqlRelationalTableModel的使用,使用该类建立关系模式,显示外键的值。

sqlbrowser

QMetaObject类包含关于Qt对象的元信息。这个类通常不是应用程序编程所需要的,但是如果您编写元应用程序(例如脚本引擎或GUI构建器),它就非常有用。如果连接为空,则 使用QMetaObject::invokeMethod,调用browser的addConnection函数。

只有QSQLITE支持在内存中创建数据库。

这个例子比较全面。

1.建立新数据库,会将起加入树形表里面,connectionWidget使用了类提升,提升可以将UI的控件用自己的类定义,比自定义控件方便。点击树形链表中相应的项的时候,表格会相应的显示选中表的数据,同时表格中的数据还可以右击进行添加、删除、回滚、提交等操作。sqlEdit的文本可作为sql语句,可以执行sql语句,并在状态栏显示错误、成功、以及受影响的记录数。还可以显示每一个属性列的一些属性。

2.这个例子除QSQLITE外其它属性列都连接不了,应该是环境变量没有响应的数据库的问题。暂时不管。

sqlwidgetmapper

这个例子讲如何使用小部件映射器和QComboBox小部件之间的命名映射,并使用一个特殊用途的模型将模型中的值与选项列表关联起来。使用QSqlRelationalTableModel建立关系模式。QDataWidgetMapper使用toPrevious()、toNext槽函数可以方便的切换。QComboBox还可以显示其它记录。

tablemodel

QSqlTableModel的简单使用范例

你可能感兴趣的:(QT,数据库,qt,mysql)