1. Qt连接Sqlite数据库的基本语句
//Qt中以数据库连接名来管理数据库连接,即 连接名 和 数据库连接 一一对应
//数据中是否存在连接connName,返回bool
QSqlDatabase::contains(connName)
//(当数据库连接不存在时)添加数据库连接并返回,参数1为驱动名,参数2为连接名
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connName);
//为数据库连接设置要操作的数据库文件(.db)
db.setDatabaseName(dbFile);
//(当数据库连接已存在时)返回该数据库连接
QSqlDatabase::database(connName)
//打开数据库连接,返回bool数据库打开是否成功
db.open();
//测试数据库连接是否已经连接,返回bool
db.isOpen()
//关闭数据库连接
db.close();
//执行数据操作数据库
QSqlQuery sqlQuery(db);
sqlQuery.exec(sql);
//不需要返回值的操作可以写作
QSqlQuery sqlQuery(db);
bool flag = sqlQuery.exec(sql);
//需要返回值得操作可以写作
//通过QSqlQuery::next()不断获取数据行
QSqlQuery *sqlQuery = new QSqlQuery(t);
sqlQuery->exec(sql);
return sqlQuery;
//删除数据库连接connName
QSqlDatabase::removeDatabase(connName);
2. 封装数据库操作类DBMana
使用QMutex 对 连接 加锁,适用于多线程,但建议经常同时操作同一数据库的线程 使用 不同的连接名,因为锁的互斥等待会增大处理时间。
(数据库中实际的连接名是"dbFile+connName",但若使用此类的封装则不用关心实际的连接名)
//共有函数
//以connName连接对数据库dbFile执行sql语句,该sql语句无返回值,函数返回执行成功/失败
//若该连接已存在则则获取,不存在则创建再获取
static bool execute(QString sql, QString connName = "DBMana", QString dbFile = "systemData.db");
//以connName连接对数据库dbFile执行sql语句,该sql语句有返回值,通过QSqlQuery::next()不断获取数据行
//若该连接已存在则则获取,不存在则创建再获取
static QSqlQuery* select(QString sql, QString connName = "DBMana", QString dbFile = "systemData.db");
//删除db文件dbFile的connName连接和其对应的锁
static void destroyConn(QString connName = "DBMana", QString dbFile = "systemData.db");
//删除db文件dbFile的所有连接和锁
static void destroyOneDBConn(QString dbFile = "systemData.db");
//删除所有db文件的所有连接和锁
static void destroyAllDBConn();
3. 详细代码
详细代码和使用方式放在了github中。
#ifndef DBMANA_H
#define DBMANA_H
#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMutex>
#include <QMap>
//数据库操作类
//使用QMutex 对 连接 加锁,适用于多线程
//但建议经常同时操作同一数据库的线程 使用 不同的连接名,因为锁的互斥等待会增大处理时间
//(数据库中实际的连接名是"dbFile+connName",但若使用此类的封装则不用关心实际的连接名)
class DBMana : public QObject
{
Q_OBJECT
public:
//以connName连接对数据库dbFile执行sql语句,该sql语句无返回值,函数返回执行成功/失败
//若该连接已存在则则获取,不存在则创建再获取
static bool execute(QString sql, QString connName = "DBMana", QString dbFile = "systemData.db");
//以connName连接对数据库dbFile执行sql语句,该sql语句有返回值,通过QSqlQuery::next()不断获取数据行
//若该连接已存在则则获取,不存在则创建再获取
static QSqlQuery* select(QString sql, QString connName = "DBMana", QString dbFile = "systemData.db");
//删除db文件dbFile的connName连接和其对应的锁
static void destroyConn(QString connName = "DBMana", QString dbFile = "systemData.db");
//删除db文件dbFile的所有连接和锁
static void destroyOneDBConn(QString dbFile = "systemData.db");
//删除所有db文件的所有连接和锁
static void destroyAllDBConn();
private:
//获取对于dbFile文件的数据库连接connName
//有则返回,没有则创建再返回
static QSqlDatabase getSqlDataBase(QString connName, QString dbFile);
//同步锁,外层key是db文件名,内层key是该db文件的数据库连接名
static QMap<QString, QMap<QString, QMutex*>> mutexMap;
};
#endif // DBMANA_H
#include "dbmana.h"
QMap<QString, QMap<QString, QMutex*>> DBMana::mutexMap;
bool DBMana::execute(QString sql, QString connName, QString dbFile)
{
QSqlDatabase t = getSqlDataBase(connName, dbFile);
mutexMap[dbFile][connName]->lock();
if (!t.isOpen())
t.open();
QSqlQuery sqlQuery(t);
bool flag = sqlQuery.exec(sql);
mutexMap[dbFile][connName]->unlock();
return flag;
}
QSqlQuery* DBMana::select(QString sql, QString connName, QString dbFile)
{
QSqlDatabase t = getSqlDataBase(connName, dbFile);
mutexMap[dbFile][connName]->lock();
if (!t.isOpen())
t.open();
QSqlQuery *sqlQuery = new QSqlQuery(t);
sqlQuery->exec(sql);
mutexMap[dbFile][connName]->unlock();
return sqlQuery;
}
void DBMana::destroyConn(QString connName, QString dbFile)
{
if (!QSqlDatabase::contains(dbFile + connName))
return;
QSqlDatabase t = QSqlDatabase::database(dbFile + connName);
if (t.isOpen())
t.close();
QSqlDatabase::removeDatabase(dbFile + connName);
delete mutexMap[dbFile][connName];
mutexMap[dbFile].remove(connName);
if (mutexMap[dbFile].keys().length() == 0)
mutexMap.remove(dbFile);
}
void DBMana::destroyOneDBConn(QString dbFile)
{
foreach (QString i, mutexMap[dbFile].keys())
{
destroyConn(i, dbFile);
}
}
void DBMana::destroyAllDBConn()
{
foreach (QString i, mutexMap.keys())
{
destroyOneDBConn(i);
}
}
QSqlDatabase DBMana::getSqlDataBase(QString connName, QString dbFile)
{
if (!QSqlDatabase::contains(dbFile + connName))
{
QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", dbFile + connName);
database.setDatabaseName(dbFile);
if (!mutexMap.contains(dbFile))
{
QMap<QString, QMutex*> tMap;
mutexMap.insert(dbFile, tMap);
}
QMutex *mutex = new QMutex();
mutexMap[dbFile].insert(connName, mutex);
}
return QSqlDatabase::database(dbFile + connName);
}