mysql8.x实践系列(2)Qt客户端怎么操作PostgreSql数据库?怎么保存和读取二进制图片?

1、Windows安装PostgreSql

(1)安装

https://www.postgresql.org/download/windows/
https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
安装时,去掉勾选pgadmin4
端口5432
初始数据库postgres
用户名postgres

密码***

(2)远程链接

postgresql是支持远程连接的数据库,默认安装以后出于安全性考虑只支持本地访问,需要做设置才能支持远程访问。postgressql需要打开安装目录下的

C:\Program Files\PostgreSQL\14\data\pg_hba.conf文件。

记事本打开,末尾新增这句话:

host    all             all             0.0.0.0/0               md5

(3)windows服务

win+r输入services.msc,可以快捷进入服务

2、用户自己写的qt操作PostgreSql的应用程序,发布时,除了需要qt官方安装路径下的数据库插件,

\Qt\Qt5.12.11\5.12.11\msvc2017_64\plugins\sqldrivers\

还需要带上PostgreSql有关的动态库文件,它们可以在安装路径下找到,C:\Program Files\PostgreSQL\14\bin

3、保存二进制图片

(1)设计表,把二进制图片定义为bytea类型

(2)源码实现

void save()
{    
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    db.setHostName("192.168.0.111");
    db.setDatabaseName("dbhappy");
    db.setPort(5432);
    db.setUserName("postgres");
    db.setPassword("admin");
    bool ok = db.open();
    if (ok)
    {
        qDebug() << "db open ok";
    }
    else
    {
        qDebug() << "db open ng";
    }

    QPixmap pix("d:\\test.jpg");
    QByteArray inByteArray;
    QBuffer inBuffer(&inByteArray);
    inBuffer.open(QIODevice::WriteOnly);
    pix.save(&inBuffer, "JPG");

    //方法1
    QSqlQuery query;
    QString sql = "INSERT INTO hello(id, image) VALUES(:id, :image)";
    query.prepare(sql); //使用bindValue就一定要prepare
    query.bindValue(":id", 11);
    query.bindValue(":image", inByteArray);
    //if (!query.exec(sql))//这是错误的写法
    if (!query.exec())
    {
        qDebug() << TIMEMS << query.lastError().text();
    }

    //方法2
    QVariant var(inByteArray);
    sql = "INSERT INTO hello(id, image) VALUES(?, ?)";
    query.prepare(sql);
    query.addBindValue(22);
    query.addBindValue(var);
    //if (!query.exec(sql))//这是错误的写法
    if (!query.exec())
    {
        qDebug() << TIMEMS << query.lastError().text();
    }

    inBuffer.close();
}

(3)结果

4、读取二进制图片

void load()
{
    //查询
    sql = "SELECT image from hello WHERE id=:id";
    query.prepare(sql); //使用bindValue就一定要prepare
    query.bindValue(":id", 11);
    //if (!query.exec(sql))//这是错误的写法
    if (!query.exec())
    {
        qDebug() << TIMEMS << query.lastError().text();
    }

    QVariant result;
    if (query.next())
    {
        result = query.value(0);
    }

    QByteArray outByteArray = result.toByteArray();
    QPixmap outPixmap = QPixmap();
    outPixmap.loadFromData(outByteArray);
    outPixmap.save("d:\\out.jpg", "jpg", 100);
}

常规的查询方式:

//查询语句
QString sql = "select UserName, UserPwd from UserInfo";

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

5、如果不想使用QPixmap,而是使用QImage来操作二进制图片,那么

QImage转化为QByteArray:

//方法1:
QImage image;
QByteArray ba;
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
image.save(&buffer,"PNG");
//image.save(&buffer, "JPG", 100);
ba.append(buffer.data());
buffer.close();
//方法2:
QImage image;
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
//image.save(&buffer, "JPG", 100);
buffer.close();

QByteArray转化为QImage:

QImage image;
QByteArray ba;
image.loadFromData(ba);

6、QPixmap保存文件

QPixmap outPixmap;
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly))
{
    return false;
}

//方式1
outPixmap.save(filePath, "PNG");

//方式2
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
outPixmap.save(&buffer, "JPG", 100);
file.write(ba);
file.close();

---

参考文献

https://www.cnblogs.com/ivint/p/14448589.html

题外话

1、如果是MySQL数据库,设计表,需要把二进制图片定义为mediumblob或者longblob类型

TinyBlob 最大 255字节
Blob 最大 65K
MediumBlob 最大 16M
LongBlob 最大 4G

在估算最大实际使用上限的情况下,能用小的就用小的,效率高。

2、如果是MySQL数据库,设计表,提供了四种TEXT类型:TINYTEXT,TEXT,MEDIUMTEXT,和LONGTEXT

TINYTEXT – 255个字节(255个字符)

TEXT – 64KB(65,535个字符)

MEDIUMTEXT – 16MB(16,777,215个字符)

LONGTEXT – 4GB(4,294,967,295个字符)

3、如果是MySQL数据库,设计表,datetime类型,那么怎么插入数据?

DATETIME 格式的语法:

YYYY-MM-DD HH:MM:SS

INSERT INTO vatsa(Dt) VALUES('2020-09-14 23:18:17');

#define TIMEMS   qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
#define DATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"))

QImage image("d:\\你好.jpg");
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "JPG", 100);

//插入数据库
QVariantMap params;
params["id"] = 0;
params["datetime"] = DATETIME; // eg."2020-09-14 23:18:17";
params["image"] = ba;
params["result"] = 3;

if (DBUtil::insert(DBCONN_NAME_MYSQL, "INSERT INTO pic (id, datetime, image, result) VALUES (:id, :datetime, :image, :result)", params) == -1)
{
    return false;
}

buffer.close();

4、如果是SQLite数据库,保存二进制图片,请看官方教程

https://wiki.qt.io/How_to_Store_and_Retrieve_Image_on_SQLite

x、姊妹篇

https://blog.csdn.net/libaineu2004/article/details/126371724

猜你喜欢

转载自blog.csdn.net/libaineu2004/article/details/127216861