创建一个基于SQLITE数据库的类

来源:互联网 发布:战地使命召唤知乎 编辑:程序博客网 时间:2024/06/06 00:20

先直接上代码


//dataBaseSQL.h

#ifndef _DATABASE_SQL_#define _DATABASE_SQL_#include <QObject>#include <QtDebug>#include <QSqlDatabase>#include <QSqlQuery>#include <QSqlRecord>#include <QSqlError>#include <QSqlDriver>#include <QMessageBox>class DatabaseSQL :public QObject{Q_OBJECTpublic:DatabaseSQL();~DatabaseSQL();bool openDatabase(int num , QSqlDatabase db);//建立数据库,项目所在文件夹生成.db文件bool recordData(QString str , QSqlDatabase db);//向数据库中插入数据bool commitTransaction(QSqlDatabase db);//更新数据库int addDatabase(int num);//增加新数据库};#endif


//dataBaseSQL.cpp

#include "DatabaseSQL.h"#pragma execution_character_set("utf-8")DatabaseSQL::DatabaseSQL(){}DatabaseSQL::~DatabaseSQL(){}bool DatabaseSQL::openDatabase(int num , QSqlDatabase db){QString num_db = QString("%1 %2").arg(num, 0, 10).arg(".db");db.setDatabaseName(num_db);db.open();return true;}bool DatabaseSQL::recordData(QString str , QSqlDatabase db){QSqlQuery query;bool success = query.exec("CREATE TABLE IF NOT EXISTS student(id INT PRIMARY KEY,name VARCHAR)");//必须加上if not exists否则重复创建表会报错if (success){qDebug() << QObject::tr("success");}else{qDebug() << QObject::tr("fail");qDebug() << query.lastError().type();QMessageBox::critical(0, QObject::tr("Database Error"),query.lastError().text());}db.transaction();//开始事务query.prepare("INSERT INTO student(id,name) VALUES(:id,:name)");query.bindValue(":name", QString(str));success = query.exec();if (!success){qDebug() << QObject::tr("in_fail");qDebug() << query.lastError().type();QMessageBox::critical(0, QObject::tr("Database Error"),query.lastError().text());}else{qDebug() << QObject::tr("in");}return true;}bool DatabaseSQL::commitTransaction(QSqlDatabase db){db.commit();return true;}int DatabaseSQL::addDatabase(int num){num++;return num;}

具体介绍一下这个类的功能。首先,在创建数据库之前需要先建立数据库连接

在你要使用该类前,需要在想使用该类的cpp文件中的构造函数中加上这样一行代码 QsqlDatabase db = QsqlDatabase::addDatabase("QSQLITE"); 

其含义是:以“QSQLITE”为数据库类型,在本进程地址空间内创建一个SQLite数据库。

静态函数QSqlDatabase::addDatabase()返回一条新建立的数据库连接。

随后,openDatabase函数要实现的就是创建数据库的过程。我们可以看到该函数有两个形参,一个是我们刚才提到的db,还有一个是num。这个参数对于建立数据库来说不是必须的,但是由于我所需要实现的功能有一项是要在每次打开串口时都新建立一个数据库,所以需要这样一个变量来更改数据库名称从而建立一个新的数据库。例如先在构造函数中初始化num为1,创建数据库,该数据库被命名为1.db。在执行关闭串口操作时调用addDatabase函数,num自加1保存。在下次打开串口时,num变为2,创建数据库即为2.db。


建立完数据库以后,我们需要在数据库中创建表格并记录数据

创建表格时用到的是SQL语句,不复杂,按照例子操作即可,但是需要注意的一点是,如果这个程序你不是只运行一次的话,在建立表格时需要这么写

CREATE TABLE IF NOT EXISTS
如果不这么写,第一次运行时不会有问题,但是在在下次运行时就会提示你该表格已经存在无法执行操作。因为你已经建立过这个表格,不允许再建立同名表格。当然你也可以选择
删除掉创建语句的命令或者是将表格改一个名字,但是相对来说要麻烦很多,不如在每次创建表格时都加上这么一句。这在网上很多关于数据库表格创建的例子中都没有提到,但是
确实是一个容易出现并且容易被忽略的问题。
在记录数据方面,有一点必须要说一下。
如果你要在短时间内向数据库内传入大量数据,建议开启事务,也就是db.transaction()。因为在不开启事务的情况下,数据库记录的机制是打开-记录-关闭-打开-记录-关闭
这样的一个循环。在数据量大的情况下效率非常低,且容易出现记录出错的情况。例如,我用串口传入数据定时发送“123”,发送间隔为100ms,在不开启事务的情况下经常会
出现某一条记录为“123123”的情况。关于事务的解释大家可以自行百度,我对此的理解很简单,不开事务时是每接收到一条数据就更新一次数据库,开启事务时是在出现db.commit()
命令前都不更新数据库,出现该命令时一次性全部更新,这样就能大大加快速度并提高准确性。
这个类目前比较简单,后续还要继续完善,像创建表格等操作都可以在函数中自行修改这里只是举个例子。之后有什么心得体会再与大家分享。