QT读写Sqlite数据库三种方式

QT对一些基本的数据库的访问封装,可谓是极大的方便的我们开发人员,现在我们就来说下QT对Sqlite这个数据库的读写,Sqlite是一个比较小型的本地数据库,对于保存一些软件配置参数或量不是很大的数据是相当的方便,Qt本身已经自带了Sqlite的驱动,直接使用相关的类库即可,这篇我们主要来说明QT访问Sqlite数据库的三种方式(即使用三种类库去访问),分别为QSqlQuery、QSqlQueryModel、QSqlTableModel,对于这三种类库,可看为一个比一个上层,也就是封装的更厉害,甚至第三种QSqlTableModel,根本就不需要开发者懂SQL语言,也能操作Sqlite数据库。
1、首先使用QSqlQuery来访问
      我们先要在工程中包含与数据库相关的几个头文件#include <QtSql/QSqlDatabase> 、#include <QtSql/QSqlRecord>、#include <QtSql/QSqlQuery>
访问的数据库内容结构为:

#include <QtWidgets/QApplication>

#include <QCoreApplication>

#include <QDebug>

 
#include <QtSql/QSqlDatabase>

#include <QtSql/QSqlQuery>

#include <QtSql/QSqlRecord>

 
typedef struct _testInfo //假定数据库存储内容

{

QString UsreName;

QString IP;

QString Port;

QString PassWord;

QString Type;

 
}testInfo;

 
int main(int argc, char *argv[])

{

QApplication a(argc, argv);

 
QVector<testInfo> infoVect; //testInfo向量,用于存储数据库查询到的数据

 
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

 
db.setDatabaseName(QApplication::applicationDirPath() + "/CONFIG/" + "CONFIG.db");

if (!db.open())

{

return 0;

}

 
/**************************使用QSqlQuery操作数据库**************************/

QSqlQuery query; //执行操作类对象

 
//查询数据

query.prepare("SELECT * FROM T_USER_MANAGE");

query.exec(); //执行

 
QSqlRecord recode = query.record(); //recode保存查询到一些内容信息,如表头、列数等等

int column = recode.count(); //获取读取结果的列数

QString s1 = recode.fieldName(0); //获取第0列的列名

 
while (query.next())

{

testInfo tmp;

tmp.UsreName = query.value("UsreName").toString();

tmp.IP = query.value("IP").toString();

tmp.Port = query.value("Port").toString();

tmp.PassWord = query.value("PassWord").toString();

tmp.Type = query.value("Type").toString();

 
infoVect.push_back(tmp); //将查询到的内容存到testInfo向量中

}

 
for (int i=0; i<infoVect.size(); i++) //打印输出

{

qDebug() << infoVect[i].UsreName << ":" 

<< infoVect[i].IP << ":" 

<< infoVect[i].Port << ":" 

<< infoVect[i].PassWord << ":" 

<< infoVect[i].Type;

}

 
//插入数据

query.prepare("INSERT INTO T_USER_MANAGE (UsreName, IP, Port, PassWord, Type) VALUES (:UsreName, :IP, :Port, :PassWord, :Type)");

query.bindValue(":UserName", "user4"); //给每个插入值标识符设定具体值

query.bindValue(":IP", "192.168.1.5");

query.bindValue(":Port", "5004");

query.bindValue(":PassWord", "55555");

query.bindValue(":Type", "operator");

query.exec();

 
 
//更改表中 UserName=user4 的Type属性为admin

query.prepare("UPDATE T_USER_MANAGE SET Type='admin' WHERE UserName='user4'");

query.exec();

 
//删除表中 UserName=user4的用户信息

query.prepare("DELETE FROM T_USER_MANAGE WHERE UserName='user4'");

query.exec();

 
#endif

2、使用QSqlQueryModel来访问

    QSqlQueryModel类带有Model字样,相信你已经猜到我们可以用他来关联试图,就能把数据库的内容显示到视图上,当然,常规的操作也是可以的,但是我们只说说怎么用这个类来把数据库中的内容显示到是视图中,这里我们选择的视图类为QTableView,直接上代码吧
 

#include <QtWidgets/QApplication>

#include <QCoreApplication>

#include <QDebug>

#include <QString>

#include <QTableView>

 
#include <QtSql/QSqlDatabase>

#include <QtSql/QSqlQueryModel>

 
int main(int argc, char *argv[])

{

QApplication a(argc, argv);

 
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

 
db.setDatabaseName(QApplication::applicationDirPath() + "/CONFIG/" + "CONFIG.db");

if (!db.open())

{

return 0;

}

 
QSqlQueryModel *model = new QSqlQueryModel;

model->setQuery("SELECT * FROM T_USER_MANAGE", db); //从给定的数据库db执行sql操作, db需预先制定并打开

 
int column = model->columnCount(); //获取列数

int row = model->rowCount(); //获取行数

 
model->setHeaderData(0, Qt::Horizontal, QStringLiteral("用户名")); //设置表头,如不设置则使用数据库中的默认表头

model->setHeaderData(1, Qt::Horizontal, QStringLiteral("IP地址"));

model->setHeaderData(2, Qt::Horizontal, QStringLiteral("端口"));

model->setHeaderData(3, Qt::Horizontal, QStringLiteral("密码"));

model->setHeaderData(4, Qt::Horizontal, QStringLiteral("用户类型"));

 
QTableView *view = new QTableView; //定义视图,只能用于显示,不能修改数据库

view->setFixedSize(500, 200);

view->setModel(model);

 
view->show();

 
return a.exec();

}

3、最后使用QSqlTableModel来访问
      最后我们来说说使用QSqlTableModel这个类去操作Sqlite数据库,这个类比上两个封装的更彻底,即使我们不懂SQL语言,也能实现对Sqlite数据库的操作,并且这个类也可以通过视图来显示修改数据库内容,这里我就拿这个类做了个用户管理模块,其实也可以通用与其他任何一个模块,只要在生成对象时传入sqlite的数据库名及要操作的表名即可。

    在这个例子中,我实现了一个KSDemoDlg类,其实是一个对话框类,里边包含了sqlite数据库的显示、修改等等功能,首先来看下效果(常规的增删改查功能都有):

 当我们点击增加、修改时,右边的编辑框便为可编辑状态(说明下,右边的编辑框是随着加载的数据库表变化而变化的,简而言之就是可以不做修改就能操作别的Sqlite数据库),完毕确定后便写进数据库,同时也在左边的表格中显示

#ifndef __KSDEMODLG_H__

#define __KSDEMODLG_H__

 
#include <QDialog>

#include <QPushButton>

#include <QLineEdit>

#include <QLabel>

#include <QComboBox>

#include <QGroupBox>

#include <QTableView>

#include <QtSql/QSqlTableModel>

#include <QtSql/QSqlDatabase>

 
 
class KSDemoDlg : public QDialog

{

Q_OBJECT

 
enum {UPDATE, INSERT};

int m_operator;

 
public:

explicit KSDemoDlg(QString databaseName, QString dataTableName, QWidget *parent = 0 );

~KSDemoDlg();

 
private:

 
void UiInit();

 
protected slots:

void onNewButtonClicked();

void onQueryButtonClicked();

void onUpdateButtonClicked();

void onDeleteButtonClicked();

void onPrimaryKeyLineEditEmpty(const QString & text);

void onCurrentTableViewClicked(const QModelIndex & index);

void onOKButtonClicked();

void onCancelButtonClicked();

 
private:

QSqlDatabase m_db;

QString m_DBName;

QString m_DBTableName;

 
private:

QTableView* m_TabView;

QSqlTableModel* m_model;

 
private:

QList<QLineEdit*> m_infoEditList;

QList<QLabel*> m_infoLabelList;

QPushButton m_OKButton;

QPushButton m_CancelButton;

 
private:

 
/*所有用户信息容器组*/

QGroupBox m_Group;

 
QLabel m_PrimaryKeyLabel;

QLineEdit m_PrimaryKeyLineEdit;

QPushButton m_QueryButton;

 
QPushButton m_NewButton;

QPushButton m_UpdateButton;

QPushButton m_DeleteButton;

 
/*所选择用户信息容器组*/

QGroupBox m_SelectGroup;

 
};

 
#endif // __KSDEMODLG_H__

.cpp文件
 

 
#include <QtWidgets/QApplication>

#include <QCoreApplication>

#include <QString>

#include <QFormLayout>

#include <QVBoxLayout>

#include <QHBoxLayout>

#include <QMessageBox>

#include <QtSql/QSqlRecord>

#include <QDebug>

 
#include "KSDemoDlg.h"

 
 
/**************************************************************************

* 函数名称:KSDemoDlg

* 函数功能:用户管理对话框构造函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

KSDemoDlg::KSDemoDlg(QString databaseName, QString dataTableName, QWidget *parent):QDialog(parent, Qt::WindowCloseButtonHint | Qt::WindowMinMaxButtonsHint | Qt::WindowStaysOnTopHint),

m_Group(this), m_PrimaryKeyLabel(this), m_PrimaryKeyLineEdit(this), m_QueryButton(this), m_NewButton(this), m_UpdateButton(this), m_DeleteButton(this), m_TabView(NULL),m_model(NULL),

m_OKButton(this),m_CancelButton(this), m_DBName(databaseName), m_DBTableName(dataTableName), m_operator(-1)

{

//打开数据库

 
m_db = QSqlDatabase::addDatabase("QSQLITE");

m_db.setDatabaseName(QApplication::applicationDirPath() + "/config/" + databaseName);

if (!m_db.open())

{

m_DBName = "";

m_DBTableName = "";

}

 
m_model = new QSqlTableModel(this, m_db);

m_model->setTable(m_DBTableName);

m_model->setEditStrategy(QSqlTableModel::OnManualSubmit); //手动提交后才修改

 
m_model->select();

 
m_TabView = new QTableView(this);

m_TabView->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置内容不可编辑

 
/*************关联槽函数*********************/

connect(&m_NewButton, SIGNAL(clicked()), this, SLOT(onNewButtonClicked()));

connect(&m_QueryButton, SIGNAL(clicked()), this, SLOT(onQueryButtonClicked()));

connect(&m_UpdateButton, SIGNAL(clicked()), this, SLOT(onUpdateButtonClicked()));

connect(&m_DeleteButton, SIGNAL(clicked()), this, SLOT(onDeleteButtonClicked()));

connect(&m_PrimaryKeyLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(onPrimaryKeyLineEditEmpty(const QString &)));

connect(m_TabView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(onCurrentTableViewClicked(const QModelIndex &)));

connect(&m_OKButton, SIGNAL(clicked()), this, SLOT(onOKButtonClicked()));

connect(&m_CancelButton, SIGNAL(clicked()), this, SLOT(onCancelButtonClicked()));

 
/*************模型关联视图*******************/

 
m_TabView->setModel(m_model);

 
/*************选中行为为整行选中*************/

m_TabView->setSelectionBehavior(QAbstractItemView::SelectRows);

 
/*************对话框窗体初始化***************/

UiInit();

 
/*************对话框窗体初始化***************/

setFixedSize(600, 400);

setWindowTitle(QStringLiteral("用户管理"));

}

 
/**************************************************************************

* 函数名称:UiInit

* 函数功能:用户管理对话框界面初始化

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

 
void KSDemoDlg::UiInit()

{

m_PrimaryKeyLabel.setText(m_model->headerData(0, Qt::Horizontal).toString());

m_NewButton.setText(QStringLiteral("增加"));

m_QueryButton.setText(QStringLiteral("查询"));

m_UpdateButton.setText(QStringLiteral("修改"));

m_DeleteButton.setText(QStringLiteral("删除"));

m_UpdateButton.setEnabled(true);

 
m_OKButton.setText(QStringLiteral("确定"));

m_CancelButton.setText(QStringLiteral("取消"));

 
/**************灵活增加界面右侧数据显示形式******************/

for(int i=0; i<m_model->columnCount(); i++)

{

m_infoLabelList.append(new QLabel(this));

m_infoLabelList[i]->setText(m_model->headerData(i, Qt::Horizontal).toString());

 
m_infoEditList.append(new QLineEdit(this));

m_infoEditList[i]->setEnabled(false);

}

m_OKButton.setEnabled(false);

m_CancelButton.setEnabled(false);

 
/**************灵活增加界面右侧数据显示形式 END******************/

 
QHBoxLayout *TotalHBoxLayout = new QHBoxLayout();

QVBoxLayout *TotalVBoxLayout = new QVBoxLayout();

 
QVBoxLayout *UserGroupVBoxLayout = new QVBoxLayout();

 
QHBoxLayout *UserEditHBoxLayout = new QHBoxLayout();

QHBoxLayout *UserButtonHBoxLayout = new QHBoxLayout();

 
QFormLayout *UserPrimaryKeyFormLayout = new QFormLayout();

 
QFormLayout *UserSelectFormLayout = new QFormLayout();

QHBoxLayout *UserSelectHBoxLayout = new QHBoxLayout();

QVBoxLayout *UserSelectVBoxLayout = new QVBoxLayout();

 
/*****************界面右侧group布局******************/

for (int i=0; i<m_infoLabelList.count(); i++)

{

UserSelectFormLayout->addRow( m_infoLabelList[i], m_infoEditList[i]);

}

UserSelectHBoxLayout->addWidget(&m_OKButton);

UserSelectHBoxLayout->addWidget(&m_CancelButton);

 
UserSelectVBoxLayout->addLayout(UserSelectFormLayout);

UserSelectVBoxLayout->addLayout(UserSelectHBoxLayout);

UserSelectVBoxLayout->addStretch();

 
/*****************界面右侧group布局 END******************/

 
UserPrimaryKeyFormLayout->addRow(&m_PrimaryKeyLabel, &m_PrimaryKeyLineEdit);

 
UserEditHBoxLayout->addLayout(UserPrimaryKeyFormLayout);

UserEditHBoxLayout->addWidget(&m_QueryButton);

UserEditHBoxLayout->addStretch();

 
UserButtonHBoxLayout->addWidget(&m_NewButton);

UserButtonHBoxLayout->addWidget(&m_UpdateButton);

UserButtonHBoxLayout->addWidget(&m_DeleteButton);

 
UserGroupVBoxLayout->addLayout(UserEditHBoxLayout);

UserGroupVBoxLayout->addLayout(UserButtonHBoxLayout);

 
m_Group.setLayout(UserGroupVBoxLayout);

 
TotalVBoxLayout->addWidget(&m_Group);

TotalVBoxLayout->addWidget(m_TabView);

 
TotalHBoxLayout->addLayout(TotalVBoxLayout, 3);

TotalHBoxLayout->addLayout(UserSelectVBoxLayout, 1);

 
setLayout(TotalHBoxLayout);

}

 
/**************************************************************************

* 函数名称:onNewUserButtonClick

* 函数功能:用户管理对话框界新增用户按钮槽函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onNewButtonClicked()

{

for (int i=0; i<m_infoEditList.count(); i++)

{

m_infoEditList[i]->setEnabled(true);

}

m_operator = INSERT;

m_OKButton.setEnabled(true);

m_CancelButton.setEnabled(true);

}

 
/**************************************************************************

* 函数名称:onQueryUserButtonClick

* 函数功能:用户管理对话框界查询用户按钮槽函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:廖明胜

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onQueryButtonClicked()

{

QString toFind = m_PrimaryKeyLineEdit.text();

 
QString ID = m_model->headerData(0, Qt::Horizontal).toString();

 
m_model->setFilter(ID + "='" + toFind + "'");

 
m_model->select();

}

 
/**************************************************************************

* 函数名称:onUpdateButtonClicked

* 函数功能:用户管理对话框界修改用户按钮槽函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onUpdateButtonClicked()

{

int toUpdate = m_TabView->currentIndex().row();

 
QSqlRecord recode = m_model->record(toUpdate);

 
for (int i=0; i<recode.count(); i++)

{

m_infoEditList[i]->setEnabled(true);

m_infoEditList[i]->setText(recode.value(i).toString());

}

m_operator = UPDATE;

m_OKButton.setEnabled(true);

m_CancelButton.setEnabled(true);

 
}

 
/**************************************************************************

* 函数名称:onDeleteButtonClicked

* 函数功能:用户管理对话框界删除用户按钮槽函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onDeleteButtonClicked()

{

int toDelRow = m_TabView->currentIndex().row();

 
if (QMessageBox::Ok == QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("确定要删除") + m_model->data(m_model->index(toDelRow, 0)).toString() + QStringLiteral("吗?"), QMessageBox::Ok|QMessageBox::No))

{

m_model->removeRow(toDelRow);

m_model->submitAll();

}

 
m_model->select();

}

 
/**************************************************************************

* 函数名称:onUserNameEditEmpty

* 函数功能:当m_UserNameEdit编辑框为空时,显示所有用户

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onPrimaryKeyLineEditEmpty(const QString & text)

{

if (text.isEmpty())

{

m_model->setTable(m_DBTableName); //重新关联数据库表,这样才能查询整个表

m_model->select();

}

}

 
/**************************************************************************

* 函数名称:onCurrentTableViewActived

* 函数功能:m_TableView视图选取当前行槽函数,内容映射到右侧用户编辑中

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onCurrentTableViewClicked(const QModelIndex & index)

{

if (!m_OKButton.isEnabled() || (INSERT == m_operator)) //只有可编辑并且操作为修改操作时才映射内容

{

return;

}

 
int currentRow = index.row();

 
QSqlRecord recode = m_model->record(currentRow);

 
for (int i=0; i<recode.count(); i++)

{

m_infoEditList[i]->setEnabled(true);

m_infoEditList[i]->setText(recode.value(i).toString());

}

}

 
/**************************************************************************

* 函数名称:onOKButtonClicked

* 函数功能:OKButton点击槽函数,确定修改数据库

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onOKButtonClicked()

{

for (int i=0; i<m_infoEditList.count(); i++)

{

if (m_infoEditList[i]->text().isEmpty())

{

QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("请将内容填写完整"), QMessageBox::Ok);

return;

}

}

 
switch (m_operator)

{

case INSERT:

{

if (QMessageBox::Ok == QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("请确定是否增加"), QMessageBox::Ok|QMessageBox::No))

{

int col = m_model->columnCount();

int row = m_model->rowCount();

m_model->insertRow(row);

for (int i=0; i<col; i++)

{

m_model->setData(m_model->index(row, i), m_infoEditList[i]->text());

}

 
m_model->submitAll(); //提交修改

}

}

break;

case UPDATE:

{

if (QMessageBox::Ok == QMessageBox::warning(this, QStringLiteral("提示"), QStringLiteral("请确定是否修改"), QMessageBox::Ok|QMessageBox::No))

{

int col = m_model->columnCount();

int CurrentRow = m_TabView->currentIndex().row();

for (int i=0; i<col; i++)

{

m_model->setData(m_model->index(CurrentRow, i), m_infoEditList[i]->text());

}

 
m_model->submitAll(); //提交修改

}

}

break;

default:

break;

}

 
for (int i=0; i<m_infoEditList.count(); i++)

{

m_infoEditList[i]->setText("");

m_infoEditList[i]->setEnabled(false);

}

 
m_model->select();

m_OKButton.setEnabled(false);

m_CancelButton.setEnabled(false);

}

 
/**************************************************************************

* 函数名称:onCancelButtonClicked

* 函数功能:OKButton点击槽函数,不操作

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

void KSDemoDlg::onCancelButtonClicked()

{

for (int i=0; i<m_infoEditList.count(); i++)

{

m_infoEditList[i]->setText("");

m_infoEditList[i]->setEnabled(false);

}

m_OKButton.setEnabled(false);

m_CancelButton.setEnabled(false);

}

 
/**************************************************************************

* 函数名称:~KsUserManageDlg

* 函数功能:用户管理对话框析构函数

* 输入参数:无

* 输出参数:无

* 返回数值:void

* 创建人员:

* 创建时间:2017-11-15

* 修改人员:

* 修改时间:

**************************************************************************/

 
KSDemoDlg::~KSDemoDlg()

{

qDebug() << "KSDemoDlg::~KSDemoDlg()";

m_db.close();

}

 
main函数
 

 
#include "KsTestDemo.h"

#include <QtWidgets/QApplication>

#include <QCoreApplication>

 
#include "KSDemoDlg.h"

 
int main(int argc, char *argv[])

{

QApplication a(argc, argv);

 
KSDemoDlg dlg("CONFIG.db", "T_USER_MANAGE"); //这里我们在生成KSDemoDlg类的时候,在构造函数中传入sqlite数据库名CONFIG.DB和想要操作的表T_USER_MANAGE

 
dlg.show(); //显示一下就OK

return a.exec();

}