@
前言
使用Sqlite数据可以进行一些本地参数获取,临时大数据存储。需要注意的是,如果你后面发布版本的时候,需要使添加数据库的依赖,要不让版本发布的时候,软件可能使用不了数据库的操作,然后一调试会发现数据没有加载驱动依赖。
一、相关操作
1.打开数据库
打开数据库的时候,同时也是会生成数据库的的文件。
具体实例如下:
QSqlDatabase SqlLiteObject::openDatabase(QString strDatabaseName)
{
QString strDir = QString("%1/%2").arg("C:").arg("Database");
// 如果没有文件夹,我们就先创建文件夹,用来放数据库文件
QDir dir;
if (!dir.exists(strDir))
dir.mkpath(strDir);
m_strDatabaseName = strDatabaseName;
QSqlDatabase db;
if (QSqlDatabase::contains(m_strDatabaseName))
{
// 如果是已经创建过了,就直接获取就行了
db = QSqlDatabase::database(m_strDatabaseName);
}
else
{
// 这里就是创建数据库了
QString strTempName = strDir + strDatabaseName;
db = QSqlDatabase::addDatabase("QSQLITE", m_strDatabaseName);
db.setDatabaseName(strTempName);
}
if (!db.open())
qDebug() << db.lastError().text();
return db;
}
2.关闭数据库
比较简单,直接移除数据名就可以了
bool SqlLiteObject::closeDatabase()
{
QSqlDatabase::removeDatabase(m_strDatabaseName);
return true;
}
3.创建数据库表
使用数据表名strTableName以及列名strHeaderNameList来对外创建
bool SqlLiteObject::createTable(QString strTableName, QStringList strHeaderNameList)
{
bool bRet = true;
do
{
// 必须存在表名和列表名
if (strTableName.isEmpty() || strHeaderNameList.size() <= 0)
{
bRet = false;
return bRet;
}
// m_strTableNameHeaderHash,这是一个QHash<QString,QStringList>的类型,用来支持多张表
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
m_strTableNameHeaderHash.insert(strTableName, strHeaderNameList);
// 开始组成一个创建表的sql语句
QString strCreateTable = QString(u8"CREATE TABLE %1(").arg(strTableName);
for (int i = 0; i < strHeaderNameList.size(); i++)
{
if (i < (strHeaderNameList.size() - 1))
strCreateTable = strCreateTable + strHeaderNameList[i] + QString(" VARCHAR(256)") + QString(",");
else
strCreateTable = strCreateTable + strHeaderNameList[i] + QString(" VARCHAR(256)") + QString(")");
}
bRet = excute(strCreateTable);
} while (0);
// 这里同时也创建一个csv文件,用了本地直接打开
do
{
QString strDir = QString("%1/%2/%3").arg("C:/").arg("log").arg(SAVE_DIR_NAME);
QDir dirCSV;
if (!dirCSV.exists(strDir))
dirCSV.mkpath(strDir);
QString strFilePath = strDir + "/" + QString("%1-%2.csv").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")).arg(strTableName);
static QMutex mutex;
QFile fileCSV;
if (!fileCSV.exists(strFilePath))
{
mutex.lock();
QFile file(strFilePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
{
QTextStream in(&file);
QString strText("");
for (int i = 0; i < strHeaderNameList.size(); i++)
{
if (i == 0)
strText = strHeaderNameList[i] + ",";
else if (i < (strHeaderNameList.size() - 1))
strText = strText + strHeaderNameList[i] + ",";
else
strText = strText + strHeaderNameList[i];
}
in << strText << '\n';
file.close();
}
mutex.unlock();
}
} while (0);
return bRet;
}
4.删除表
直接执行删除数据表语句
bool SqlLiteObject::dropTable(QString strTableName)
{
if (strTableName.isEmpty())
return false;
QString strDrop = QString("DROP TABLE %1").arg(strTableName);
return excute(strDrop);
}
5.执行数据库语句
为了解决线程的问题,我们这里采用的是打开数据库后再去执行数据库语句。
bool SqlLiteObject::excute(QString strSql)
{
bool bRet = true;
QSqlDatabase db = openDatabase(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QSqlQuery query(db);
query.prepare(strSql);
bool success = query.exec(strSql);
if (!success)
{
qDebug() << "Error:" << query.lastError();
bRet = false;
}
closeDatabase();
return bRet;
}
6.数据库查询
我们直接将查询后的数据直接缓存到一个哈希表里面,这样我们应用层要使用的时候,再从哈希表里面获取。
QList< QHash<QString/*name*/, QString/*value*/> > SqlLiteObject::select(QString strTableName, QString strName, QString strValue)
{
QList< QHash<QString, QString> > temp;
if (strTableName.isEmpty() || strTableName.isEmpty())
return temp;
QSqlDatabase db = openDatabase(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QString strSelect("");
if (!strValue.isEmpty())
strSelect = QString("SELECT * FROM %1 WHERE %2 = '%3';").arg(strTableName).arg(strName).arg(strValue);
else
strSelect = QString("SELECT * FROM %1;").arg(strTableName);
db.transaction(); // 开启事务查询
QSqlQuery query("", db);
query.exec(strSelect);
db.commit(); // 提交事务
while (query.next())
{
QHash<QString, QString> keyValueHash;
int nCount = query.record().count();
for (size_t i = 0; i < nCount; i++)
keyValueHash.insert(query.record().fieldName(i), query.record().value(i).toString());
if (keyValueHash.size() > 0)
temp << keyValueHash;
}
closeDatabase();
return temp;
}
7.数据库插入
插入数据库的同时,也保存到本地csv文件,方便用文本直接打开查看内容。
bool SqlLiteObject::insert(QString strTableName, QHash<QString/*name*/, QString/*value*/> dataHash)
{
bool bRet = false;
if (strTableName.isEmpty())
return bRet;
QStringList strHeaderList;
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
return bRet;
else
strHeaderList = m_strTableNameHeaderHash[strTableName];
// 缓存到csv文件里面
do
{
QString strDir = QString("%1/%2").arg("C:/").arg("Database");
QString strFilePath = strDir + "/" + QString("%1-%2.csv").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")).arg(strTableName);
static QMutex mutex;
mutex.lock();
QFile file(strFilePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
{
QTextStream in(&file);
QString strMessage;
for (size_t j = 0; j < strHeaderList.size(); j++)
{
QString strName = strHeaderList[j];
QString strValue = "";
auto findName = dataHash.find(strName);
if (findName != dataHash.end())
strValue = findName.value();
if (j == 0)
strMessage = strValue + ",";
else if (j < (strHeaderList.size() - 1))
strMessage = strMessage + strValue + ",";
else
strMessage = strMessage + strValue;
}
in << strMessage << '\n';
file.close();
}
mutex.unlock();
} while (0);
// 插入数据库
do
{
QString strInsert = QString("INSERT INTO %1 VALUES(").arg(strTableName);
for (size_t j = 0; j < strHeaderList.size(); j++)
{
QString strName = strHeaderList[j];
QString strValue = "";
auto findName = dataHash.find(strName);
if (findName != dataHash.end())
strValue = findName.value();
if (j < (strHeaderList.size() - 1))
strInsert = strInsert + QString("'%1'").arg(strValue) + QString(",");
else
strInsert = strInsert + QString("'%1'").arg(strValue) + QString(")");
}
bRet = excute(strInsert);
} while (0);
return bRet;
}
8.模糊查询
有时候我们界面需要一些自动补全的功能,那么这个时候,模糊查询就是我们要用的方式。
QStringList SqlLiteObject::fuzzySearch(QString strTableName, QString strName, QString strLike)
{
QStringList temp;
if (strTableName.isEmpty() || strTableName.isEmpty())
return temp;
QSqlDatabase db = openDatabase(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QString strSelect("");
if (!strLike.isEmpty())
strSelect = QString("SELECT %1 FROM %2 WHERE %3 LIKE '%%4%' LIMIT 0,10;").arg(strName).arg(strTableName).arg(strName).arg(strLike);
else
return temp;
db.transaction(); // 开启事务查询
QSqlQuery query("", db);
query.exec(strSelect);
while (query.next())
{
QHash<QString, QString> keyValueHash;
for (size_t i = 0; i < query.record().count(); i++)
{
QString strName = query.record().fieldName(i);
QString strValue = query.record().value(i).toString();
if (!temp.contains(strValue) && (strLike != strValue))
temp << strValue;
}
}
db.commit(); // 提交事务
closeDatabase();
return temp;
}
打赏