目录
一、前言
二、相关步骤
三、提示
四、源码/Demo
本节讲述QT sql数据库使用方案,并提供一个访问数据库的封装类,最后关于发布时的提示
①工程文件加入sql模板
QT += sql
②创建CDbMain类单例,用来连接数据库
创建单例的好处在于不用经常开关数据库和创建多次类,单例在整个工程都能使用。单例部分可看我的博文《QT单例模式(函数模板实现)》
CDbMain.h
#ifndef __CDBECMAIN_H__
#define __CDBECMAIN_H__
#include
#include
#include "CSingleMode/TSingleMode.h"
//数据库管理,单例模式
class CDbMain : public TSingleMode
{
friend class TSingleMode;
public:
CDbMain();
~CDbMain();
public:
QSqlDatabase GetDataBase();
bool ConnectDB();
void DisConnectDB();
private:
const QString m_csConnectionName;
};
#endif
CDbMain.cpp
#include "CDbMain.h"
#include
#include
#include
#include
CDbMain::CDbMain()
: m_csConnectionName("DB_TEST")
{
ConnectDB();
}
CDbMain::~CDbMain()
{
DisConnectDB();
}
QSqlDatabase CDbMain::GetDataBase()
{
QSqlDatabase db = QSqlDatabase::database(m_csConnectionName);
return db;
}
bool CDbMain::ConnectDB()
{
if (QSqlDatabase::database(m_csConnectionName).isOpen())
{
return true;
}
//添加数据库驱动、设置数据库名称、数据库登录用户名、密码
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", m_csConnectionName);
//数据库的路径,建议设为绝对路径
QString sDbFile = QCoreApplication::applicationDirPath() + "/database.db";
db.setDatabaseName(sDbFile);
qDebug() << "[Drivers]:" << QSqlDatabase::drivers();
qDebug() << "[DB PATH]:" << sDbFile;
//打开数据库
if(!db.open())
{
qDebug() << QString(sDbFile).append(" not open");
return false;
}
return true;
}
//关闭数据库
void CDbMain::DisConnectDB()
{
QSqlDatabase::database(m_csConnectionName).close();
QSqlDatabase::removeDatabase(m_csConnectionName);
}
③创建数据库指令CSqlQuery类,封装数据库结构
CSqlQuery.h
#ifndef _CSQL_QUERY_H
#define _CSQL_QUERY_H
#include
#include
#include
#include
class CSqlQuery : public QSqlQuery
{
public:
CSqlQuery();
virtual ~CSqlQuery();
static void closeDbConnection();
public:
QString GetSqlErrCodeStr();
//插入
bool InsertQuery(const QString& sTableName, const QString& sValues, const QString& sFields = QString());
//删除
bool DeleteQuery(const QString& sTableName, const QString& sWheCondition = QString());
//更新
bool UpdateQuery(const QString& sTableName, const QString& sSetFields, const QString& sWheCondition = QString());
//选择
bool SelectQuery(const QString& sFields, const QString& sTableName, const QString& sWheCondition = QString(),
const QString& sOrderCondition = QString(), int nLimNum = -1, int nOffNum = -1);
bool createTableTest();
private:
QMutex* m_pMutex;
};
#endif
CSqlQuery.cpp
#include "CSqlQuery.h"
#include "CDbMain.h"
#include
#include
#include
#include
#include
#include
CSqlQuery::CSqlQuery() : QSqlQuery(CDbMain::getInstance()->GetDataBase())
{
m_pMutex = new QMutex;
}
CSqlQuery::~CSqlQuery()
{
if(m_pMutex != NULL)
{
m_pMutex->unlock();
m_pMutex = NULL;
}
}
void CSqlQuery::closeDbConnection()
{
CDbMain::deleteInstance();
}
//获取报错信息
QString CSqlQuery::GetSqlErrCodeStr()
{
m_pMutex->lock();
QSqlError qsqlErr = CDbMain::getInstance()->GetDataBase().lastError();
m_pMutex->unlock();
switch(qsqlErr.type())
{
case QSqlError::NoError:
return "No Error!";
case QSqlError::ConnectionError:
return "Failed to connect!";
case QSqlError::StatementError:
return "Statement error!";
case QSqlError::TransactionError:
return "Transaction error!";
case QSqlError::UnknownError:
return "Unknown error!";
}
return QString();
}
/*
*功能: 插入数据
*sTableName[IN]: 表名
*sValues[IN]: 数值
*sFields[IN]: 表项
*/
bool CSqlQuery::InsertQuery( const QString& sTableName, const QString& sValues, const QString& sFields )
{
QString sQuery;
if (!sFields.isEmpty())
{
sQuery = QString("insert into %1(%2) values(%3);").arg(sTableName).arg(sFields).arg(sValues);
}
else
{
sQuery = QString("insert into %1 values(%2);").arg(sTableName).arg(sValues);
}
qDebug() << sQuery;
m_pMutex->lock();
bool bRet = exec(sQuery);
m_pMutex->unlock();
return bRet;
}
/*
*功能: 删除数据
*sTableName[IN]: 表名
*sWheCondition[IN]: 条件(可选)
*/
bool CSqlQuery::DeleteQuery( const QString& sTableName, const QString& sWheCondition )
{
QString sQuery;
if (!sWheCondition.isEmpty())
{
sQuery = QString("delete from %1 where %2;").arg(sTableName).arg(sWheCondition);
}
else
{
sQuery = QString("delete from %1;").arg(sTableName);
}
qDebug() << sQuery;
m_pMutex->lock();
bool bRet = exec(sQuery);
m_pMutex->unlock();
return bRet;
}
/*
*功能: 更新数据
*sTableName[IN]: 表名
*sSetFields[IN]: 数值
*sWheCondition[IN]: 条件(可选)
*/
bool CSqlQuery::UpdateQuery( const QString& sTableName, const QString& sSetFields, const QString& sWheCondition )
{
if (sSetFields.isEmpty())
{
return true;
}
QString sQuery;
if (!sWheCondition.isEmpty())
{
sQuery = QString("update %1 set %2 where %3;").arg(sTableName).arg(sSetFields).arg(sWheCondition);
}
else
{
sQuery = QString("update %1 set %2;").arg(sTableName).arg(sSetFields);
}
qDebug() << sQuery;
m_pMutex->lock();
bool bRet = exec(sQuery);
m_pMutex->unlock();
return bRet;
}
/*
*功能: 获取数据
*sFields[IN]:表项
*sTableName[IN]: 表名
*sWheCondition[IN]: 条件(可选)
*nLimNum[IN]、nOffNum[IN]:限制项(可选)
*/
bool CSqlQuery::SelectQuery( const QString& sFields, const QString& sTableName, const QString& sWheCondition
, const QString& sOrderCondition, int nLimNum, int nOffNum)
{
QString sQuery;
if (!sWheCondition.isEmpty())
{
sQuery = QString("select %1 from %2 where %3").arg(sFields).arg(sTableName).arg(sWheCondition);
}
else
{
sQuery = QString("select %1 from %2").arg(sFields).arg(sTableName);
}
if (!sOrderCondition.isEmpty())
{
sQuery.append(" ").append(QString("order by %3").arg(sOrderCondition));
}
if (nLimNum!=-1 && nOffNum != -1)
{
sQuery.append(" ").append(QString("limit %1 offset %2").arg(nLimNum).arg(nOffNum));
}
qDebug() << sQuery;
m_pMutex->lock();
bool bRet = exec(sQuery);
m_pMutex->unlock();
return bRet;
}
/*
*功能: 创建表格(调试)
*/
bool CSqlQuery::createTableTest()
{
QString sQuery = "CREATE TABLE IF NOT EXISTS [ClassA] ([ID] INTEGER NOT NULL PRIMARY KEY,[Name] VARCHAR(64) NOT NULL,[Age] INTEGER NOT NULL,[Score] INTEGER NOT NULL,[Teacher] VARCHAR(64) NOT NULL)";
m_pMutex->lock();
bool bRet = exec(sQuery);
m_pMutex->unlock();
return bRet;
}
④使用方法/案例
//创表
void MainWindow::on_pushButton_create_clicked()
{
CSqlQuery query;
bool bRet = query.createTableTest();
if(!bRet)
{
QString sErr = query.GetSqlErrCodeStr();
ui->textEdit->append(sErr);
}
}
//插入
void MainWindow::on_pushButton_insert_clicked()
{
CSqlQuery query;
bool bRet = query.InsertQuery("ClassA", "'xiaoMing',18,97,'Martin'", "Name,Age,Score,Teacher");
if(!bRet)
{
QString sErr = query.GetSqlErrCodeStr();
ui->textEdit->append(sErr);
}
}
//获取数据
void MainWindow::on_pushButton_select_clicked()
{
CSqlQuery query;
bool bRet = query.SelectQuery("ID,Name,Age,Score,Teacher", "ClassA");
if(bRet)
{
while (query.next())
{
QString str = QString("%1,%2,%3,%4,%5").arg(query.value(0).toInt()).arg(query.value(1).toString())
.arg(query.value(2).toInt()).arg(query.value(3).toInt())
.arg(query.value(4).toString());
ui->textEdit->append(str);
}
}
else
{
QString sErr = query.GetSqlErrCodeStr();
ui->textEdit->append(sErr);
}
}
②把相关运行库放入,其中包括sql的库,发布相关内容可看我的博客《QT在Windows下发布版本(Release)》
②发布的时候,要将你安装的QT/plugins/sqldrivers文件夹拷贝到exe执行程序目录下,只需要qsqlite4的相关库即可(单纯release可以只需要qsqlite4.dll文件,Debug模式则只需要qsqlite4d.dll);否则会报错“Driver not loaded Driver not loaded”,找不到数据库驱动所以显示这个。
③不相干的tips
凡是看到后缀有..d的库,例如本例qsqlite4d.dll库,其实都是debug里需要的库,只是在debug模式下,QT Creator默认帮你调用了,如果想自己点开exe文件,就需要相关的库。同理,没有后缀..d的库,例如本例qsqlite4.dll库,都是release里需要的库。
可在本页CSDN下载