Content Table

Qt5 乱码

Qt5 强制要求源码的编码必须使用 UTF-8,不过,即使我们的源码都是 UTF-8 的了,仍然会遇到乱码问题,例如

  • MinGW 编译没问题的工程使用 VS 编译时有可能报错
  • MinGW 编译的程序运行时中文正常显示,VS 下编译通过,运行时却是乱码

通常有下面几种情况导致中文乱码:

  • 源码不是 UTF-8 的
  • 源码是 UTF-8 的,但 BOM 导致乱码 (VS 的需要 BOM,而 Linux,Mac 下默认是没有 BOM 的)
  • 非 UTF-8 的运行环境导致乱码

下面来解决 Qt5 的乱码问题。

数据库访问工具 DBUtl

数据库访问工具 DBUtil

DBUtil 用于简化数据库的访问,只要准备好配置文件,调用 DBUtil 的静态函数就能直接得到查询数据库的结果。

本文主要内容有:

  • 数据库访问的思考
  • DBUtil 实例
  • DBUtil 的 API
  • DBUtil 的实现
  • 把 SQL 语句放到文件里
  • ORMapping

数据库连接池

在前面的章节里,我们使用了下面的函数创建和取得数据库连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void createConnectionByName(const QString &connectionName) {
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connectionName);
db.setHostName("127.0.0.1");
db.setDatabaseName("qt"); // 如果是 SQLite 则为数据库文件路径
db.setUserName("root"); // 如果是 SQLite 不需要
db.setPassword("root"); // 如果是 SQLite 不需要

if (!db.open()) {
qDebug() << "Connect to MySql error: " << db.lastError().text();
return;
}
}

QSqlDatabase getConnectionByName(const QString &connectionName) {
return QSqlDatabase::database(connectionName);
}

虽然抽象出了连接的创建和获取,但是有几个弊端:

  • 需要我们维护连接的名字,不小心就重名了
  • 获取连接的时候需要传入连接的名字
  • 获取连接的时候不知道连接是否正在被使用,很容易一个线程中获取另外一个线程创建的数据库连接
  • 每次调用 createConnectionByName() 都会创建一个新的连接
  • 连接断开后不会自动重连
  • 需要手动释放连接

数据库常用操作

前面的章节介绍了怎么使用 Qt 连接访问数据库 SQLite 和 MySQL,在这一节里将介绍访问数据库的常用操作,主要内容有:

  • QSqlDatabase
  • 查询
    • 使用 Prepared Query 查询
    • SQL 注入
    • 使用 LIKE 模糊查询
    • 解决列名冲突
  • 更新
  • 删除
  • 事务

访问 MySql

Qt 里访问 MySQL 是件很简单的事,但也有可能很不简单。说其简单是因为熟悉的人都知道只需要有 MySQL 的驱动插件和复制 MySQL 的动态链接库到程序可识别的环境变量的路径下即可,对于不熟悉的人来说,看到 Qt 给我们的错误信息简单到 QMYSQL driver not loaded,从这一句简单的提示里却找不到任何头绪,不知道应该怎么做,在网络上搜索了很多文章,照着做有的人问题解决了,有的人试过了很多种方法问题仍然存在。在这一节里,我们会一步一步的来分析,解决访问 MySQL 的问题。访问其他数据库也可以用同样的方法解决。

访问 SQLite

SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。 其特点是高度便携、使用方便、结构紧凑、高效、可靠。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。SQLite 支持跨平台,同一个 SQLite 的数据库文件,可以在 Windows,Linux,Mac OS 中使用。SQLite 的使用非常广泛,例如 Firefox,Chrome,Android,iOS 等都使用了 SQLite 来存储数据。SQLite 默认不支持使用用户名密码来连接,如果我们的数据安全性要求不高,那么就可以使用 SQLite 来存储,这样做的好处是数据文件是一个单一的文件,可以和项目一起发布而不需要安装数据库软件就能拥有数据库的功能,这是多么美好的事(想像一下,如果需要模拟数据库的操作,手动用程序通过读写文件的方式向一个文件中插入,更新,删除一条记录需要付出多少的代价,而用 SQLite 的话,就是一条 SQL 语句的事情,用上 SQLite,这简直是鸟枪换炮了啊)。

Qt 默认已经提供了 SQLite 的驱动,直接在代码里就可以访问 SQLite。在 plugins/sqldrivers 目录下可以找到 SQLite 的数据库驱动插件。

数据库

Qt 是用 C++ 实现的,那么 C,C++ 访问数据库的方式也同样适用于 Qt,如要访问 MySQL,需要相应的头文件和库文件(例如 Windows 下的 dll 或者 lib,Linux 下的 .so 或者 .a),如果你安装了 MySQL,会在安装目录下找到这些库文件,如果没有安装,也可以在网上找到,在代码里 #include "MySQL Headers",然后用提供的函数访问 MySQL。访问 Sqlite,Oracle 等任何一个数据库,都和访问 MySQL 差不多,需要它们自己的头文件和库文件,使用它们提供的函数访问数据库。

组播

夜深人静,一个小黑屋子里发出神秘的嘀嘀嘀……嗒嗒嗒……嘀嘀嘀…… 的声音,谍战剧必不可少的画面

Multicast 和发电报有相似之处,一条消息发送给多个既定的目标群体。