日常开发中,需要保存一些软件运行用到的一些数据,比如软件设置或者软件读入的数据,这些数据我以前一般都是会写成一个类或者结构体去保存,简单的我会按一定的分隔符组合成字符串,然后需要保存的时候一行一个,保存成txt,在需要读取的时候一次性读入,再按分隔符分割.这样做的好处是可以代码写得很快,保存跟恢复十几行代码就搞定了,但是后期维护起来超级麻烦,配置文件一大堆,而且效率也不是很高,每次都得是整体读入写出,即时性保存不是很方便.而且这种代码看起来很”蠢”,比如下面这个:
真的很怕 address 里面突然包含个 # ……
复杂的话,我会使用数据库,比如最钟爱的SQLite,但是使用数据库就没那么快速了,首先要先设计表,然后要想办法保证这个数据库存在(如果数据库不存在,要使用sql语句创建对应的表,这个也比较麻烦),然后数据的增删改查都需要在持有数据库的连接的情况下去写对应的sql语句了,代码量比较大.不过好在这些都写完以后后期维护就简单多了,效率也不错,可以随时使用sql语句查询需要的数据.
大多数时间不急的情况下,我都会选择是SQLite,天生对一堆文本配置文件很反感,在多次的SQLite的使用中,我也逐渐摸索除了一些可以减少代码书写量的一些办法,最近正好有需求要用到SQLite数据库,索性就总结了一下经验,写出了一个SQLite版的”对象数据库”,在使用上我本来想尽量往ObjectBox(一个目前在Android上推出的基于对象的数据库,速度超快,我的实测数据比SQLite快了五倍的样子,有兴趣的可以去试试)靠拢,但是好多用法都想不到办法去实现,索性就另辟蹊径了,目前现在来看,我的用法也不比ObjectBox复杂,某些方面甚至可以说更简单一点.所谓基于对象的数据库,我的理解就是数据操作是基于对象的,而不是去操作某个Table里面的某行,不过我这里是用sqlite数据库去模拟,所以我是一张表就对应了一个类.反之,一个类我就用一张表去保存.为了简化操作,我在notepad++上写了一个插件,差不多是一键完成数据库到类的生成工作.
框架使用步骤(以Qt为例,Java类似)
比如我有这么一个表:
(1).由数据库生成对应的的类.
有了数据库以后可以使用我在notepad++上写的一个插件一步完成类的生成和注册代码,自动生成的代码如下:
头文件:
#ifndef __7ef8d26d_d64a_4257_bae5_93d8dd24dadc_H__
#define __7ef8d26d_d64a_4257_bae5_93d8dd24dadc_H__
#include <QString>
#include "qtsqlitetool.h"
class Person :public SqlTableBase
{
public:
Person();
Person(QSqlQuery query);
virtual QString tableName() const override;
virtual QString sqlWhere() const override;
virtual QStringList itemNames() const override;
virtual QString createStr() const override;
virtual void updateWhere() override;
virtual QString dbGuid() const override;
virtual bool insertIntoDb() override;
virtual bool updateToDb() override;
virtual bool removeFromDb() override;
virtual QVariantMap contentValues() const override;
QString toString() const ;
bool init(QString str);
QString getName() const;
void setName(QString val);
int getAge() const;
void setAge(int val);
QString getIDCard() const;
void setIDCard(QString val);
private:
QString m_sqlwhere;
QString m_Name;
int m_Age;
QString m_IDCard;
};
#endif // __7ef8d26d_d64a_4257_bae5_93d8dd24dadc_H__
CPP文件:
#include "person.h"
#include <QJsonObject>
#include <QJsonDocument>
Person::Person()
{
}
Person::Person(QSqlQuery query)
{
m_Name = query.value("Name").toString();
m_Age = query.value("Age").toInt();
m_IDCard = query.value("IDCard").toString();
updateWhere();
}
QString Person::tableName() const
{
return "Person";
}
QString Person::sqlWhere() const
{
return m_sqlwhere;
}
QStringList Person::itemNames() const
{
return QStringList() << "Name"<< "Age"<< "IDCard";
}
QString Person::createStr() const
{
return "CREATE TABLE Person( Name VARCHAR, Age INTEGER, IDCard VARCHAR)";
}
void Person::updateWhere()
{
m_sqlwhere = QString(" Name = '%1' ").arg(m_Name);
}
QVariantMap Person::contentValues() const
{
QVariantMap val;
val.insert("Name", m_Name);
val.insert("Age", m_Age);
val.insert("IDCard", m_IDCard);
return val;
}
QString Person::dbGuid() const
{
return "051e1ae7_aba9_48d9_ba6f_17ce5afe9730";
}
bool Person::insertIntoDb()
{
SqlItemInsert
}
bool Person::updateToDb()
{
SqlItemUpdate
}
bool Person::removeFromDb()
{
SqlItemRemove
}
QString Person::toString() const
{
QVariantMap varmap = contentValues();
QJsonDocument doc = QJsonDocument::fromVariant(QVariant(varmap));
QByteArray jba = doc.toJson();
QString jsonString = QString(jba);
return jsonString;
}
bool Person::init(QString str)
{
QByteArray njba = str.toUtf8();
QJsonObject nobj = QJsonObject(QJsonDocument::fromJson(njba).object());
QVariantMap query = nobj.toVariantMap();
m_Name = query.value("Name").toString();
m_Age = query.value("Age").toInt();
m_IDCard = query.value("IDCard").toString();
updateWhere();
return true;
}
QString Person::getName() const
{
return m_Name;
}
void Person::setName(QString val)
{
m_Name = val;
}
int Person::getAge() const
{
return m_Age;
}
void Person::setAge(int val)
{
m_Age = val;
}
QString Person::getIDCard() const
{
return m_IDCard;
}
void Person::setIDCard(QString val)
{
m_IDCard = val;
}
注册cpp:
#include "qtsqlitetool.h"
#include "person.h"
BeginDbRegister
RegisterDB(Person)
EndDbRegister
其中用到的依赖可以在notepad++导出,只有一个cpp及头文件
(2).初始化并打开数据库:
QtSqliteToolManager::instance()->openDb(dbPath,Person().dbGuid());
参数第二项可以是该数据库任意类取出的guid即可.
(3)数据插入
Personp;
…//p的赋值操作
boolisok = p.insertIntoDb();//isok代表是否插入数据库成功(如类没有正确注册或者数据库没打开就会失败)
(4)数据删除
boolisok = p. removeFromDb ();
(5)数据更新
boolisok = p.updateToDb();
(6)查询数据
QList<Person>pers = QueryToList<Person>();//查询出所有的Person并填充到list里面
//这个函数还可以接where和order两个参数,实现筛选和排序(默认为空) 如:
QList<Person> pers =QueryToList<Person>("Age> 18","Na