- Access中并没有BLOB或者CLOB类型字段,要将文件的二进制数据存放在Access中,需要使用的是Access的OLE对象字段,让人觉得不爽的是Access软件没有MySQL Query Broswer那样直接查看二进制数据,导出文件,甚至作为图像文件直接打开的功能,除非是将二进制大对象包装成OLE对象 。(这是题外话,但是的确给工作带来不便)
回到Qt,Qt中要进行二进制大对象的数据库操作,数据传送部分主要是两个类QByteArray和QVariant (Qt里面的数据库操作都会用到QVariant类)。
用过Qt的朋友应该对QByteArray都比较熟悉,QByteArray为Qt提供了二进制数据缓冲区的服务,除了提供缓冲区的分配,删除,扩展等管理外,还提供了很多类似字符串需要的操作,诸如查找,替换,填充之类。更重要的是QByteArray是引用计数和写时拷贝的,可以被多个只读的客户对象所共享。
QByteArray为QString,QImage,QPixmap等类提供了缓冲区的资源管理服务,这是一个现代的C++的做法,把资源管理的职责从功能类中抽离,为了提供更好的重用性和健壮性。
QVarint既是所谓的变体数据类型 ,Qt提供了它自己的实现(变体数据类型在脚本语言或者象VB这种弱类型语言中,通常语言本身就已经直接提供支持,C++中类似的实现非常多,MFC,Qt,boost库都有自己的实现)。
QVariant缺省已经支持所有基本数据类型和Qt Core库中的所有类类型,也可以通过扩展支持其它的数据类型 (如Qt GUI库中的类型和用户的自定义类型)。
插入数据的基本步骤是:
1:得到一个含有要存放的二进制数据的QByteArray对象。
2:把QByteArray包装成QVariant对象。
3:绑定QVariant对象到QSqlQuery数据库查询对象的相应数据字段
4:执行QSqlQuery
读取数据的步骤刚好相反:
1:执行SELECT语句的QSqlQuery
2:获得相应字段的QVariant对象
3:获得QVaraint对象里面的QByteArray对象
下面的例程说明了如何将一个图像的影像数据作为二进制大对象存放到Access数据库中:
上图中Image字段是一个OLE对象。
void
AlignmentTester::logAccessDB(
const
TestInputData
&
input,
const
AlignmentResultData
*
result)
const
{
static const QString INSERT = QString("INSERT INTO AlignmentResult "
"(Serial_ID, TestDate, TestTime, CAM_PITCH_Vert, CAM_YAW_Horiz, CAM_ROLL, Result, Image) "
"VALUES (:Serial_ID, :TestDate, :TestTime, :CAM_PITCH_Vert, :CAM_YAW_Horiz, :CAM_ROLL, :Result, :Image)");
QSqlDatabase db;
if (CTPDatabase::getDBConnection(db))
{
//构造一个在数据库连接之上执行的SqlQuery对象
QSqlQuery query(db);
//准备插入语句
query.prepare(INSERT);
//绑定值
query.bindValue(":Serial_ID", result->getSerialID());
query.bindValue(":TestDate", result->getTestDate());
query.bindValue(":TestTime", result->getTestTime());
query.bindValue(":CAM_PITCH_Vert", result->getRealBiasAngleY());
query.bindValue(":CAM_YAW_Horiz", result->getRealBiasAngleX());
query.bindValue(":CAM_ROLL", result->getRotateAngle());
query.bindValue(":Result", result->isPass() ? "Pass" : "Fail");
//获得QImage的影像数据(QByteArray 对象)
QByteArray imageData;
QBuffer buffer(&imageData);
buffer.open(QIODevice::WriteOnly);
input.getImage().save(&buffer, "bmp");
//将获得的QByteArray对象包装成QVariant对象并绑定到QSqlQuery对象
//注意 - 这里会由一个隐式转换发生,因为QVariant提供了参数类型为QByteArray的构造函数
query.bindValue(":Image", imageData);
if(!query.exec())//执行数据库插入操作
{
QSqlError error = query.lastError();
CTP_DEBUG(
QString("Insert Aligment record error : %1.").
arg(error.text()));
}
db.close();
}
}
插入的结果: