1. Qt提供的对不同数据库的驱动支持:
Driver Type Description:
QDB2 IBM DB2
QIBASE Borland InterBase Driver
QMYSQL MySQL Driver
QOCI Oracle Call Interface Driver
QODBC ODBC Driver (includes Microsoft SQL Server)
QPSQL PostgreSQL Driver
QSQLITE SQLite version 3 or above
QSQLITE2 SQLite version 2
QTDS Sybase Adaptive Server
2 .创建连接Oracle数据库实例:
- QSqlDatabase db = QSqlDatabase::addDatabase("QOCI", "OracleA");
- db.setHostName("localhost"); //数据库主机名
- db.setDatabaseName("scott"); //数据库名
- db.setUserName("stott"); //数据库用户名
- db.setPassword("tiger"); //数据库密码
- db.open(); //打开数据库连接
- db.close(); //释放数据库连接
在使用
QSqlDatabase::addDatabase(
"QOCI","OracleA"
)函数时,
第一个参数是驱动类型主键,第二个是连接名。
//qsqldatabase.cpp文件
class QConnectionDict: public QHash<QString, QSqlDatabase>
{
public:
inline bool contains_ts(const QString &key)
{
QReadLocker locker(&lock);
return contains(key);
}
inline QStringList keys_ts() const
{
QReadLocker locker(&lock);
return keys();
}
mutable QReadWriteLock lock;
};
Q_GLOBAL_STATIC(QConnectionDict, dbDict)
Qt定义了一个全局
QHash
容器用来存储这个进程里所有的数据库连接对象,存储格式QHash<连接名,QSqlDatabase
>。
每次调用addDatabase接口都会检查这个容器里是否有这个连接,有的话断开之前的连接,建立现在加入的,没有直接
添加这个连接。
如果进程里涉及到操作多个不同数据库,则每个数据库的对象在添加连接时要区别开不一样的连接名,如果连接名相同,会使上一个已经建立的连接失效。
如果进程里多处地方(比如不同的线程)只连接到一个数据库,则需要把QSqlDatabase对象封装为全局对象(静态或者封装单例),所有的操作对象都使用这个数据库连接对象来进行操作。
(举例:进程中多个线程都建立了一个封装数据库操作的对象,他们都需要连接到一个数据库,所以单例就可以保证连接一次到处引用。如果想保持你线程里有一个独立的连接数据库操作对象,就需要调用addDatabase("device","connectName")连接名要不同于其他线程建立的,不然其他线程在操作数据库将无效)
3.使用QSqlQuery类操作数据库:
bool InsertData(cosnt Users &users)
{
m_pqReportDB.transaction(); //使用数据库事务操作对下面批量插入性能会提高很多
QSqlQuery sqlQuery(db); //使用已经打开成功的QSqlDatabase数据库对象驱动
for(int i= 0; i <users.size(); i++)
{
sqlQuery.prepare("insert into tables(id, name) values(?,?)");
sqlQuery.addBindValue(users[i].id); //还可以使用bindValue接口,参数绑定
sqlQuery.addBindValue(users[i].name);
if (!sqlQuery.exec())
{
QSqlError error = sqlQuery.lastError();
PQ_LOG_ERROR(error.text()); //记录错误日志
m_pqReportDB.rollback(); //遇到错误,事务回滚
return false;
}
}
m_pqReportDB.commit();//提交事务,批量插入执行
return true;
}