﻿1. Qt5默认提供的数据库插件包括了QSQLITE、QMYSQL、QPSQL、QODBC四种，其中驱动打印中还有个QMYSQL3是表示mysql3旧版本，现在默认一般都mysql5以上，QPSQL7表示postgres7旧版本，现在默认一般都postgres9以上。
2. 根据字面意思很容易理解QSQLITE用来连接sqlite数据库，QMYSQL用来连接mysql数据库，QPSQL用来连接postgres数据库，QODBC理论上可以用来连接任何支持ODBC数据源的数据库，比如access、sqlserver、mysql、postgres、oracle等。
3. Qt4默认提供的数据库插件只有QSQLITE、QODBC两种，因为QODBC理论上可以用来连接任何支持ODBC数据源的数据库，只是通过了微软的数据源中间件，效率上可能会有损耗，所以在Qt5又新增了其他几个常用数据库的插件比如QMYSQL、QPSQL，而其他数据库由于协议的要求并没有提供对应的插件需要自行编译比如oracle。
4. Qt内置了sqlite数据库，可以观察到qsqlite4.dll文件大小明显比其他数据库插件大很多，理论上光一个插件应该小很多才对，毕竟sqlite属于小型数据库，所以肯定是将sqlite的源码直接编译到插件了，所以我们在使用sqlite数据库的时候无需带一个sqlite.dll，而使用mysql则需要带上libmysql.dll。
5. 使用mysql、postgres等支持远程访问的数据库的时候，并不需要本地安装数据库，只需要发布程序的时候带上对应数据库的动态库即可，比如mysql对应带上libmysql.dll即可，这样程序指定数据库主机地址就可以连接上，比如阿里云的mysql、postgres等云端数据库。
6. mysql、posgrest等支持远程连接的数据库，默认安装以后出于安全性考虑只支持本地访问，需要做设置才能支持远程访问，mysql需要增加用户root@%即主机设置为%，postgres需要打开安装目录下的C:\PostgreSQL\10\data\pg_hba.conf文件，增加一行 host all all 192.168.1.0/24 md5 表示支持192.168.1.1到192.168.1.255的IP访问，同时将C:\PostgreSQL\10\data\postgresql.conf改成listen_addresses = '*'表示支持所有地址，具体这个的含义可以自行搜索。
7. mysql数据库通信的默认端口是3306，postgres的是5432，这些端口都可以在安装的时候或者后期更改。
8. 数据库也有位数的区别，比如你连接的是64位的数据库那就需要用64位的Qt以及64位的数据库插件和对应的动态库文件，位数一定要完全一致才行，否则连不上，很多人会在这个地方摔一跤。除了位数的区别可能还要注意版本的区别，毕竟数据库一直在更新升级换代，有些版本变动比较大，未必Qt发布版本的时候对应就支持最新的数据库，所以一般建议用稍微老一点的数据库版本，比如mysql本人一直用5.6，测试到现在Qt5.13版本都支持。
9. 一般的软件默认都只需要连接一个数据库，所以建议直接在程序启动以后就打开好数据库，然后其他需要用到数据库的地方就执行即可，最后程序关闭的时候关闭数据库。很多初学者每次增删改查都打开数据库执行完成操作以后然后关闭数据库，这样效率极其低下。如果需要连接多个数据库，则以数据库连接名称作为区分，Qt支持同时多个数据库连接的，数据库跨线程不安全，要加锁，所以建议在哪个线程使用到的数据库就在那个线程中打开，而不要主线程打开数据库子线程使用数据库，很可能会出问题。Qt5.10开始增加了数据库跨线程使用的安全性检查，运行时会打印提示。
10. 创建数据库、创建表、创建索引、初始化数据等这些都可以通过执行sql语句来实现，强烈建议在对常用的数据量比较多的表创建表的时候要创建索引，在大量的数据查询更新操作的时候先启动数据库事务，执行完成以后提交数据库事务。

数据库操作一般流程代码
``` c++
void MainWindow::testDb()
{
    //打印当前Qt对应支持的数据库驱动名称
    qDebug() << QSqlDatabase::drivers();

    //创建数据库对象,驱动名称根据打印的填写,"QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7"
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    //设置数据库参数,要查看Qt文档是否支持该数据库,一般建议默认的就好不用设置
    //db.setConnectOptions("MYSQL_OPT_RECONNECT=1;MYSQL_OPT_CONNECT_TIMEOUT=1;");
    //设置数据库的主机地址
    db.setHostName("127.0.0.1");
    //设置数据库通信端口,默认值  mysql:3306  postgres:5432  sqlserver:1433
    db.setPort(5433);
    //设置数据库名称,默认值  mysql:mysql  postgres:postgres  sqlserver:master
    //如果是sqlite数据库只需要设置这个参数即可,其余参数都不用设置,因为sqlite不需要主机端口和用户
    //参数内容为数据库文件的路径 db.setDatabaseName("c:/test.db");
    db.setDatabaseName("postgres");
    //设置登录用户名称,默认值  mysql:root  postgres:postgres  sqlserver:sa
    db.setUserName("postgres");
    //设置登录用户密码
    db.setPassword("admin");
    //打开数据库,如果失败打印错误信息
    if (!db.open()) {
        qDebug() << db.lastError();
        return;
    }

    //执行增删改查
    //常规查询语句
    QString sql = "select UserName,UserPwd from UserInfo";
    //带条件+排序+分组的查询语句
    sql = "select UserName,UserPwd from UserInfo where UserName='admin' order by UserName asc group by UserGroup";

    //构建查询对象,传入sql语句查询,可以先判断执行成功与否再来取值
    QSqlQuery query;
    if (query.exec(sql)) {
        //循环取出所有查询结果,对应结果是QVariant类型可以自行to到其他类型
        while(query.next()) {
            qDebug() << query.value(0).toString() << query.value(1).toString();
        }
    }

    //添加数据,拼接字符串的形式比较通用,还有占位符的形式
    sql = "insert into UserInfo(UserName,UserPwd) values('ceshi', '12345')";
    //删除数据,如果不加where条件则表示删除整个表的数据
    sql = "delete from UserInfo where UserName='ceshi'";
    //更新数据,如果不加where条件则表示更新整个表的数据
    sql = "update UserInfo set UserPwd='admin123' where UserName='ceshi'";

    //可以复用上面的QSqlQuery对象,也可以重新new,复用的话需要先调用clear
    query.clear();
    //添加+删除+更新 数据只需要知道执行成功与否就行
    if (!query.exec(sql)) {
        qDebug() << "执行sql语句失败";
    }

    //关闭数据库,程序自动关闭的时候也会关闭,所以只是用一个数据库的情况下无需手动关闭
    db.close();
}

```