连接数据库时,以ODBC连接数据库,需要配置ODBC,觉得有点麻烦。如果用ADO连接,省事。程序只需要置一下数据源即可。对应各种数据库(ORACLE,SQLSERVER,MYSQL等)都能轻松应对。
一、设置ORACLE的连接串
调用例:conn.connectToOracle(“orcl”, “localhost”, 1521, “scott”, “tiger”);
bool AdoConnection::connectToOracle(
const QString& strServiceName,
const QString& host,
int port,
const QString& strUserName,
const QString& strPwd)
{
QString strOracle =
"Provider=OraOLEDB.Oracle;Password=" + strPwd+
";Persist Security Info=True;User ID=" + strUserName+
";Data Source=(DESCRIPTION = (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST =" + host+ ") " +
"(PORT = " +QString::asprintf("%d", port)+")))"+
"(CONNECT_DATA =(SERVICE_NAME =" + strServiceName+"))) "
;
return open(strOracle);
}
二、创建QAxObject对象
创建连接对象:
m_pAxObject = new QAxObject(this);
m_pAxObject->setControl(“ADODB.Connection”);
创建结果集对象
m_pAxObject = new QAxObject(this);
m_pAxObject->setControl(“ADODB.Recordset”);
三、AdoConnection类
头文件adoconnection.h
#ifndef ADOCONNECTION_H
#define ADOCONNECTION_H
#include <QObject>
#include <QtCore>
#include <QVariant>
#include <QAxObject>
class AdoConnection:public QObject
{
Q_OBJECT
public:
AdoConnection(QObject *parent=nullptr);
~AdoConnection();
bool open(const QString & connectString);
bool execute(const QString & sql);
bool open();
void close();
QVariant connection();
bool isOpen() const;
bool connectToOracle(
const QString& strServiceName,
const QString& host,
int port,
const QString& strUserName,
const QString& strPwd);
private:
QAxObject* m_pAxObject;
QString m_strOpenString;
QTimer* m_pTimer;
signals:
public slots:
void exception(int /*code*/, const QString & /*source*/, const QString & /*desc*/, const QString & /*help*/);
void disconnect();
private:
};
#endif // ADOCONNECTION_H
CPP文件adoconnection.cpp
#include "adoconnection.h"
#include <adodef.h>
#include <QtDebug>
#include <QTimer>
#include "ADO.h"
AdoConnection::AdoConnection(QObject *parent)
: QObject(parent)
{
m_pTimer = new QTimer(this);
Q_CHECK_PTR(m_pTimer);
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(disconnect()));
m_strOpenString ="";
m_pAxObject = new QAxObject(this);
m_pAxObject->setControl("ADODB.Connection");
//qDebug() << "Timeout" << m_pAxObject->property("ConnectionTimeout");
m_pAxObject->setProperty("ConnectionTimeout",300);
connect(m_pAxObject,SIGNAL(exception(int,const QString&,const QString&,const QString &)),
this,SLOT(exception(int,const QString&,const QString&,const QString &)));
}
AdoConnection::~AdoConnection()
{
if(isOpen())
{
close();
}
}
void AdoConnection::exception(int code, const QString & source, const QString & desc, const QString & help)
{
qDebug() << "Code: " << code;
qDebug() << "Source: " << source;
qDebug() << "Description:" << desc;
qDebug() << "Help: " << help;
}
bool AdoConnection::open(const QString& connectString)
{
if(isOpen()) return true;
m_strOpenString = connectString;
HRESULT hr = m_pAxObject->dynamicCall("Open(QString,QString,QString,int)",connectString,"","",adConnectUnspecified).toInt();
return SUCCEEDED(hr);
}
bool AdoConnection::open()
{
if(m_strOpenString.isEmpty()) return false;
bool ret = open(m_strOpenString);
if(m_pTimer && m_pTimer->isActive()) m_pTimer->stop();
return ret;
}
bool AdoConnection::execute(const QString & sql)
{
if(!open()) return false;
HRESULT hr = m_pAxObject->dynamicCall("Execute(QString)",sql).toInt();
return SUCCEEDED(hr);
}
void AdoConnection::disconnect()
{
if(isOpen())
m_pAxObject->dynamicCall("Close");
if(m_pTimer) m_pTimer->stop();
//qDebug() << "AdoConnection::disconnect()";
}
void AdoConnection::close()
{
if(m_pTimer)
{
if(m_pTimer->isActive()) m_pTimer->stop();
m_pTimer->start(5000);
}
else
disconnect();
}
QVariant AdoConnection::connection()
{
return m_pAxObject->asVariant();
}
bool AdoConnection::isOpen() const
{
return (bool)(m_pAxObject->property("State").toInt() != adStateClosed);
}
bool AdoConnection::connectToOracle(
const QString& strServiceName,
const QString& host,
int port,
const QString& strUserName,
const QString& strPwd)
{
QString strOracle =
"Provider=OraOLEDB.Oracle;Password=" + strPwd+
";Persist Security Info=True;User ID=" + strUserName+
";Data Source=(DESCRIPTION = (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST =" + host+ ") " +
"(PORT = " +QString::asprintf("%d", port)+")))"+
"(CONNECT_DATA =(SERVICE_NAME =" + strServiceName+"))) "
;
return open(strOracle);
}
四、AdoRecordset类
头文件adorecordset.h
#ifndef ADOCONNECTION_H
#define ADOCONNECTION_H
#include <QObject>
#include <QtCore>
#include <QVariant>
#include <QAxObject>
class AdoConnection:public QObject
{
Q_OBJECT
public:
AdoConnection(QObject *parent=nullptr);
~AdoConnection();
bool open(const QString & connectString);
bool execute(const QString & sql);
bool open();
void close();
QVariant connection();
bool isOpen() const;
bool connectToOracle(
const QString& strServiceName,
const QString& host,
int port,
const QString& strUserName,
const QString& strPwd);
private:
QAxObject* m_pAxObject;
QString m_strOpenString;
QTimer* m_pTimer;
signals:
public slots:
void exception(int /*code*/, const QString & /*source*/, const QString & /*desc*/, const QString & /*help*/);
void disconnect();
private:
};
#endif // ADOCONNECTION_H
源文件AdoRecordset.cpp
#include "adorecordset.h"
#include "adoconnection.h"
#include <QAxObject>
#include "ADO.h"
AdoRecordset::AdoRecordset(QObject *parent) : QObject(parent)
{
}
AdoRecordset::AdoRecordset( QVariant & conn, QObject *parent)
: QObject(parent)
{
m_pAxObject = new QAxObject(this);
m_dbConnection = conn;
m_pAxObject->setControl("ADODB.Recordset");
}
AdoRecordset::AdoRecordset(AdoConnection * adoConnection,QObject *parent)
: QObject(parent)
, m_dbConnection(adoConnection->connection())
{
m_pAxObject = new QAxObject(this);
m_pAxObject->setControl("ADODB.Recordset");
}
bool AdoRecordset::open(const QString & sql)
{
HRESULT hr = m_pAxObject->dynamicCall("Open(QString,QVariant,int,int,int)",sql,m_dbConnection,adOpenStatic,adLockOptimistic,adCmdText).toInt();
m_bInitial = true;
return SUCCEEDED(hr);
}
int AdoRecordset::recordCount() const
{
return m_pAxObject->property("RecordCount").toUInt();
}
bool AdoRecordset::next()
{
bool ret = false;
m_listFieldNames.clear();
m_listFieldValues.clear();
if(m_pAxObject->property("RecordCount").toInt() < 1) return false;
if(m_bInitial)
{
ret = move(First);
m_bInitial = false;
}
else
ret = move(Next);
if(m_pAxObject->property("EOF").toBool()) return false;
QAxObject * adoFields = m_pAxObject->querySubObject("Fields");
if(adoFields)
{
int count = adoFields->property("Count").toInt();
for(int i = 0; i < count; i++)
{
QAxObject * adoField = adoFields->querySubObject("Item(int)",i);
if(adoField)
{
m_listFieldNames += adoField->property("Name").toString();
m_listFieldValues += adoField->property("Value");
ADO_DELETE(adoField);
}
}
ADO_DELETE(adoFields);
}
return ret;
}
bool AdoRecordset::move(MoveAction action)
{
static const char * actions[] =
{
"MoveFirst(void)",
"MoveNext(void)",
"MovePrevious(void)",
"MoveLast(void)"
};
HRESULT hr = m_pAxObject->dynamicCall(actions[action]).toInt();
return SUCCEEDED(hr);
}
int AdoRecordset::fieldCount() const
{
return m_listFieldNames.count();
}
QString AdoRecordset::fieldName(int index) const
{
if(index < 0 || index >= m_listFieldNames.count()) return QString::null;
return m_listFieldNames[index];
}
QVariant AdoRecordset::fieldValue(int index) const
{
if(index < 0 || index >= m_listFieldValues.count()) return QVariant();
return m_listFieldValues[index];
}
void AdoRecordset::close()
{
m_pAxObject->dynamicCall("Close");
}
五、宏定义
#ifndef ADO_H
#define ADO_H
#include <QAxObject>
#define adOpenUnspecified -1
#define adOpenForwardOnly 0
#define adOpenKeyset 1
#define adOpenDynamic 2
#define adOpenStatic 3
#define adConnectUnspecified -1
#define adStateClosed 0
#define adLockUnspecified -1
#define adLockReadOnly 1
#define adLockPessimistic 2
#define adLockOptimistic 3
#define adLockBatchOptimistic 4
#define adCmdUnspecified -1
#define adCmdUnknown 0x8
#define adCmdText 0x1
#define adCmdTable 0x2
#define adCmdStoredProc 0x4
#define adCmdFile 0x100
#define adCmdTableDirect 0x200
#define adRsnMove 10
#define adRsnFirstChange 11
#define adRsnMoveFirst 12
#define adRsnMoveNext 13
#define adRsnMovePrevious 14
#define adRsnMoveLast 15
typedef long HRESULT;
#define SUCCEEDED(hr) ((HRESULT)hr >= 0)
#define FAILED(hr) ((HRESULT)hr < 0)
#define ADO_DELETE(p) do{ if(p) delete (p); (p) = nullptr; } while(0)
#endif // ADO_H