- 教程及其一般软件
1.源码概述
1.1. 文件QFxQSQLite.h
代码语言:javascript复制#ifndef QFXQSQLITE_H
#define QFXQSQLITE_H
#include <QObject>
#include <QStringList>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QTime>
#include <QDateTime>
#include <QtGlobal>
class QFxQSQLite : public QObject
{
Q_OBJECT
public:
QFxQSQLite(QObject *parent);
QFxQSQLite();
~QFxQSQLite();
//获取可以利用的所有SQL驱动
static QStringList getAllDrivers();
// 创造一个数据库名字
static QString createDbNameByTime();
// 由毫秒数 转换为 QTime变量
static QTime getTimeFromMSec(const int msec);
//建立数据库链接,打开创建表
bool createDbConnection(const QString& filePath, const QString& connectionName = "qt_sql_default_connection");
//插入数据
bool insertItem(const int id, const char* buf, const int len);
//更新数据库
bool updateItem(const int id, const int time);//更新 Time(第2列) 通过ID
bool updateItem(const int id, const char* buf, const int len);//更新 Buf (第3列) 通过ID
bool updateItem_ALL(const int id, const int time, const char* buf, const int len);//更新 Buf (第3列) 通过ID
//查询数据
bool getItem(const int id, int &time, char* &Buf, int &lenBuf);
//查询最大ID
bool findMaxID(int &id);
//删除
bool delItem(const int id);
//清空表格
bool delTable();
// 关闭数据库
void closeDb();
private:
QSqlDatabase m_database;
QTime m_StartTime;//记录打开数据库的时间,用于换算插入数据的时间
};
#endif // QFXQSQLITE_H
1.2. 文件QFxQSQLite.cpp
代码语言:javascript复制#include "QFxQSQLite.h"
#include <QDebug>
#pragma execution_character_set("utf-8")
QFxQSQLite::QFxQSQLite(QObject *parent)
: QObject(parent)
{
}
QFxQSQLite::QFxQSQLite()
{
}
QFxQSQLite::~QFxQSQLite()
{
}
// 静态类 beg
QStringList QFxQSQLite::getAllDrivers()
{
qDebug() << "能够支持的数据库驱动有:";
QStringList str_drivers = QSqlDatabase::drivers();
foreach(QString str_driver, str_drivers)
qDebug() << " " << str_driver.toStdString().c_str();
return str_drivers;
}
QString QFxQSQLite::createDbNameByTime()
{
QString DbName;
QTime cTime = QTime::currentTime();
QDateTime cDTime = QDateTime::currentDateTime();
DbName = cDTime.toString("[yyyyMMdd-hhmmss]") QString("RTData.db");
qDebug() << "DbName = " << DbName.toStdString().c_str();
return DbName;
}
QTime QFxQSQLite::getTimeFromMSec(const int msec)
{
QTime timeSpan(0, 0, 0, 0);
timeSpan = timeSpan.addMSecs(msec);
qDebug() << "time span: " << timeSpan.toString("hh-mm-ss:zzz");
return timeSpan;
}
// 静态类 beg
bool QFxQSQLite::createDbConnection(const QString& filePath, const QString& connectionName /*= "qt_sql_default_connection"*/)
{
// 如果数据库驱动里没有SQLite,则错误警告
//============
if (!QSqlDatabase::drivers().contains("QSQLITE"))
{
qDebug() << "Error: 系统需添加SQLite数据库驱动" << endl;
return false;
}
// 建立数据库
//============
m_database = QSqlDatabase::addDatabase("QSQLITE", connectionName );
m_database.setDatabaseName(filePath);
m_database.setUserName("NiCai");//对于SQLite无用
m_database.setPassword("123456");//对于SQLite无用
// 打开数据库
//============
if (!m_database.open())
{
qDebug() << "Error: Failed to connect database.n"
<< m_database.lastError() << endl;
return false;
}
// 创建表格
//============
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
//创建一个名为 RT_Data 的表格,表格包含三列,第一列是id,第二列是time(ms),第三列是Buf(二进制)
QString str_create_SQL = "CREATE TABLE IF NOT EXISTS RTData(Id int primary key, Time int, Buf BLOB )";
sql_query.prepare(str_create_SQL);
if (!sql_query.exec())
{
qDebug() << "Error: Fail to create table.n"
<< sql_query.lastError() << endl;
return false;
}
// 记录当前创建表格的时间
//============
m_StartTime = QTime::currentTime();
return true;
}
void QFxQSQLite::closeDb()
{
if (m_database.isOpen())
{
qDebug() << "关闭数据库" << endl;
m_database.close();
}
else
{
qDebug() << "数据库没有打开.无法关闭" << endl;
}
}
bool QFxQSQLite::insertItem(const int id, const char* buf, const int len)
{
// Table
//[ Id , Time , Buf ]
QTime cTime = QTime::currentTime();
int msecTime = m_StartTime.msecsTo(cTime);
//qDebug() << "time span(ms): " << msecTime;
QByteArray arrayBuf(buf, len);
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
QString str_insert_SQL = "INSERT INTO RTData VALUES (?, ?, ?)";//[ Id , Time , Buf ]
sql_query.prepare(str_insert_SQL);
sql_query.addBindValue( id );//ID
sql_query.addBindValue( msecTime );//Time
sql_query.addBindValue( arrayBuf );//Buf
if (!sql_query.exec())
{
qDebug() << sql_query.lastError();
qDebug("插入数据[%d] - 失败!!!!!!!!", id);
return false;//插入失败
}
qDebug("插入数据[%d] - OK!", id);
return true;
}
bool QFxQSQLite::updateItem(const int id, const int time)
{
QString str_update_SQL = "UPDATE RTData SET Time = :msec WHERE Id = :id";
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
sql_query.prepare(str_update_SQL);
sql_query.bindValue(":msec", time);
sql_query.bindValue(":id", id );
if (!sql_query.exec())
{
qDebug() << sql_query.lastError();
qDebug("更新数据[%d] Time - 失败!!!!!!!!", id);
return false;
}
qDebug("更新数据[%d] Time - OK!", id);
return true;
}
bool QFxQSQLite::updateItem(const int id, const char* buf, const int len)
{
QString str_update_SQL = "UPDATE RTData SET Buf = :ByteArray WHERE Id = :id";
QByteArray arrayBuf(buf, len);
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
sql_query.prepare(str_update_SQL);
sql_query.bindValue(":ByteArray", arrayBuf);
sql_query.bindValue(":id", id);
if (!sql_query.exec())
{
qDebug() << sql_query.lastError();
qDebug("更新数据[%d] buf - 失败!!!!!!!!", id);
return false;
}
qDebug("更新数据[%d] buf - OK!", id);
return true;
}
bool QFxQSQLite::updateItem_ALL(const int id, const int time, const char* buf, const int len)
{
QString str_update_SQL = "UPDATE RTData SET Time = :msec, Buf = :ByteArray WHERE Id = :id";
QByteArray arrayBuf(buf, len);
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
sql_query.prepare(str_update_SQL);
sql_query.bindValue(":msec", time);
sql_query.bindValue(":ByteArray", arrayBuf);
sql_query.bindValue(":id", id);
if (!sql_query.exec())
{
qDebug() << sql_query.lastError();
qDebug("更新数据[%d] time buf - 失败!!!!!!!!",id);
return false;
}
qDebug("更新数据[%d] time buf - OK!", id);
return true;
}
bool QFxQSQLite::findMaxID(int &id)
{
QString str_select_max_SQL = "SELECT MAX(Id) FROM RTData";
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
int max_id = 0;
sql_query.prepare(str_select_max_SQL);
if (!sql_query.exec())
{
qDebug("查询最大ID失败");
qDebug() << sql_query.lastError();
return false;
}
else
{
while (sql_query.next())
{
max_id = sql_query.value(0).toInt();
qDebug("find max ID: %d", max_id );
}
}
id = max_id;
return true;
}
bool QFxQSQLite::delItem(const int id)
{
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
QString str_delete_SQL = "DELETE FROM RTData WHERE Id = ?";
sql_query.prepare(str_delete_SQL);
sql_query.addBindValue(id);
if (!sql_query.exec())
{
qDebug("删除[%d] - 失败!!!!!!!!", id);
qDebug() << sql_query.lastError();
return false;
}
qDebug("删除[%d] - OK!", id);
return true;
}
bool QFxQSQLite::delTable()
{
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
QString str_clear_SQL = "DELETE FROM RTData";
sql_query.prepare(str_clear_SQL);
if (!sql_query.exec())
{
qDebug("删除-[Table] - 失败!!!!!!!!");
qDebug() << sql_query.lastError();
return false;
}
qDebug("删除-[Table] - OK!");
return true;
}
bool QFxQSQLite::getItem(const int id, int &time, char* &Buf, int &lenBuf)
{//其中char* &Buf,是为了不让传回去的Buf无法使用,这样new的才会有用,不用[引用]就得用 char **pBuf,解决问题。
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
QString str_select_SQL = "SELECT * FROM RTData WHERE Id = ?";
sql_query.prepare(str_select_SQL);
sql_query.addBindValue(id);
if (!sql_query.exec())
{
qDebug("getItem[%d] - 失败!!!!!!!!",id);
qDebug() << sql_query.lastError();
return false;
}
else
{
while (sql_query.next())
{
int getID = sql_query.value(0).toInt();
time = sql_query.value(1).toInt();
QByteArray array = sql_query.value(2).toByteArray();
lenBuf = array.size();
Buf = new char[lenBuf];
memcpy(Buf, array.data(), lenBuf);
qDebug("%d,%d, time = %d, lenArry = %d, lenBuf = %d", id, getID, time, array.size(), sizeof(Buf));
for (int i = 0; i < lenBuf; i )
{
qDebug("X", Buf[i]);
}
}
}
qDebug("getItem[%d] - OK!nTime = %d", id, time);
return true;
}
2.分析源码
2.1. 建立数据库链接,打开创建表
代码语言:javascript复制bool createDbConnection(const QString& filePath, const QString& connectionName = "qt_sql_default_connection");
bool QFxQSQLite::createDbConnection(const QString& filePath, const QString& connectionName /*= "qt_sql_default_connection"*/)
{
// 如果数据库驱动里没有SQLite,则错误警告
//============
if (!QSqlDatabase::drivers().contains("QSQLITE"))
{
qDebug() << "Error: 系统需添加SQLite数据库驱动" << endl;
return false;
}
// 建立数据库
//============
m_database = QSqlDatabase::addDatabase("QSQLITE", connectionName );
m_database.setDatabaseName(filePath);
m_database.setUserName("NiCai");//对于SQLite无用
m_database.setPassword("123456");//对于SQLite无用
// 打开数据库
//============
if (!m_database.open())
{
qDebug() << "Error: Failed to connect database.n"
<< m_database.lastError() << endl;
return false;
}
// 创建表格
//============
QSqlQuery sql_query(m_database);//不这样初始化,会出现"QSqlQuery::prepare: database not open"
//创建一个名为 RT_Data 的表格,表格包含三列,第一列是id,第二列是time(ms),第三列是Buf(二进制)
QString str_create_SQL = "CREATE TABLE IF NOT EXISTS RTData(Id int primary key, Time int, Buf BLOB )";
sql_query.prepare(str_create_SQL);
if (!sql_query.exec())
{
qDebug() << "Error: Fail to create table.n"
<< sql_query.lastError() << endl;
return false;
}
// 记录当前创建表格的时间
//============
m_StartTime = QTime::currentTime();
return true;
}
1初始设置
建立一个QSqlDatabase
对象m_database
,后续的操作都建立在这个对象上。
这句话SqlDatabase::drivers().contains("QSQLITE")
,是用静态函数SqlDatabase::drivers()
得到一个QStringList
变量,这个变量是返回能够支持的数据库种类,如果不能支持,就返回false
。
QSqlDatabase::addDatabase("QSQLITE", connectionName )
中:
- 参数1:
QSQLITE
是SQLite对应的驱动名 - 参数2:
connectionName
是自定义的连接名称(如果程序需要处理多个数据库文件的话就会这样)。Qt默认连接名称qt_sql_default_connection
,用if (QSqlDatabase::contains(connectionName))
判断链接是否存在(如果有这个需求的话)。
setDatabaseName()
的参数是数据库文件名
(可以包含路径)。如果这个数据库不存在,则会在后续操作时自动创建;如果已经存在,则后续的操作会在已有的数据库上进行。
setUserName()
和setPassword()
是设置用户名和密码,但是对于SQLite
来说没有用。
2打开数据库
使用open()
打开数据库,返回值为bool
类型,用于判断成功还是失败。
m_StartTime = QTime::currentTime();
打开数据库成功后,我会记录打开数据库的时间,用于以后记录插入每条记录的时间。
3创建表格
对数据库的操作,都是用SQLite
的语句完成的,把这些指令以QString
类型,通过QSqlQuery::prepare()
函数,保存在QSqlQuery
对象中。也可将指令,以QString
形式直接写在QSqlQuery::exec()
函数的参数中,例如:
sql_query.exec("CREATE TABLE IF NOT EXISTS RTData(Id int primary key, Time int, Buf BLOB )");
创建表格语句:
代码语言:javascript复制CREATE TABLE <table_name> (f1 type1, f2 type2,…)
CREATE TABLE
是创建表格的语句,也可用小写create table
;RTData
是表格的名称,可以任意取;括号中是表格的格式,上述指令表明,表格中有三列:
- 第一列的名称(
表头
)是Id
,这一列储存的数据类型是int
; - 第二列名称是
Time
,数据类型也是是int
,存放毫秒数
; - 第三列的名称是
Buf
,数据类型是BLOB
,用于存放二进制数据(我要存放一个char[]数组,大小为100,但是并不是字符串,里面有效数据有可能为