SQLITE3数据库读写助手(3)

概述

  • 本文将介绍前文中类SqliteExt的用法
  • SqliteExt类功能就三大类:
    • 读取slqite中表格的数据
    • 写入用户表格中的数据到文件
    • 其他功能: 执行sql语句接口......
  • 思路: 获取数据库中表每个字段的类型,根据类型移动指针给结构体赋值
  • 存放数据的内存需要按照1字节对齐, 例如,下面的结构体stTableCommonIdStr存放表common中的数据, 需要设置1字节对齐
#pragma pack(1)
struct stTableCommonIdStr
{
	int id_;
	QString name_;
};

#pragma pack()

而表common的结构为:

common中的数据为

  • SqliteExt的特点(相对常规数据库读写)

    • 读取不用调用方编写sql语句, 模块内部自动完成
    • 写入数据不用调用方编写sql语句, 模块内自动完成
  • SqliteExt不足
    后期有时间再优化与改进,先把V1.00.000开发出来, 为后面重构铺垫。

    • 目前支持的数据库字段较少,包括: INTEGER, TEXT , DOUBLE
    • 基于Qt实现,不满足通用c++使用场景

设计之初

  • sqlite数据库内容,无论是读取还是写入,都需要手动编写sql语句交由特定的函数执行
  • 如果新增字段, 就需要编写对应的字段的读写,如果遗漏, 则无法完成对应的功能
  • 单个项目的配置项可能很多,编写sql语句较为麻烦
  • 多个项目使用, 无法达到复用的目的
  • 于是,读写任意sqlite数据库表数据的念头产生了
  • 自己用的都是小项目, 使用sqlite作为配置文件,简单方便,由于项目逐渐增多,项目的配置维护成本增加

SqliteExt 使用顺序

按照下面的顺序:

  • A. 初始化,传递指定的数据库文件及相关参数
  • B. 读写表数据
  • C. 师傅资源

SqliteExt 头文件函数介绍

initialized_

功能

- 初始化函数,需要调用该函数完成模块初始化后, 方可读写数据库中的内容

使用范例

/// 0. 读取界面当前选择的是哪种
oct_sqlite::stSQLInit st_init;
{
    /// 指定打开的数据库文件
    st_init.str_sqlite_file_	= str_file;
    /// 指定数据库的编辑策略
    st_init.en_es_				= oct_sqlite::ES_MANUAL_SUBMIT;
    /// 本次需要读取数据库中的哪种数类型
    st_init.en_tt_				= static_cast<oct_sqlite::enTableType>(ui.combo_load_type->itemData(ui.combo_load_type->currentIndex()).toInt());
}

/// 1. 执行初始化
int sql_ext_init_ret			= psqlite_ext_->initialized_(st_init);
/// 2. 检查初始化结果
if (0							!= sql_ext_init_ret)
{
    return;
}

carry_on_sql_

功能

- 执行sql语句

函数原型

/// -------------------------------------------------------------------------------
/// @brief:		执行sqlite语句
/// @param: 	const QString & str_sql - sql语句
/// @param: 	const QString & str_table_name - 对数据库的那张表执行 
///  @ret:		int
///				0 - 成功
///				1 - 失败, 数据库没有初始化
///				2 - 失败, 参数str_sql 为空
///				3 - 失败, 数据库中没有[str_table_name]这张表
///				5 - 失败, 对应的数据库model没有得到
///				6 - 失败, sql语句错误
///				7 - 失败, sql语句执行失败,请检查sql语句
/// -------------------------------------------------------------------------------
int carry_on_sql_(const QString& str_sql, const QString& str_table_name) noexcept;

sql_record_

功能

- 获取sql语句的执行结果

原型

/// -------------------------------------------------------------------------------
/// @brief:		获取sql语句执行结果
/// @param: 	const QString & str_sql - 对应的sql语句
/// @param: 	const QString & str_table_name - 操作哪张表
///  @ret:		QT_NAMESPACE::QSqlQuery*
///					nullptr - sql语句或者没有[str_table_name]对应的表格, 或者创建对应的model错误
///					!= nullptr - 成功
/// -------------------------------------------------------------------------------
QSqlQuery* sql_record_(const QString& str_sql, const QString& str_table_name) noexcept;

uninitialized_

功能

- 释放模块资源,退出前请显示调用

原型

///-------------------------------------------------------------------------------
/// @brief:		释放
///  @ret:		void
///				
/// -------------------------------------------------------------------------------
void uninitialized_() noexcept;

mapTable

功能

- 调用**initialized_**函数后, 调用该函数,可获得当前表格中的数据结构

原型

/// -------------------------------------------------------------------------------
/// @brief:		获取当数据库中的表
///  @ret:		oct_sql::mapTable&
///				
/// -------------------------------------------------------------------------------
const mapTable& map_table_() noexcept;
- 其中, **mapTable**的结构的定义如下 
/// ----------------------------------------------------------------------------------------
/// @brief: 操作model
/// ----------------------------------------------------------------------------------------
struct stTableModelView_
{
    /// model
    QSqlTableModel*	pmodel_	= nullptr;
    /// view
    QTableView* pview_		= nullptr;

    void set_model_to_view_()
    {
        if (pview_)
        {
            pview_->setModel(pmodel_);
        }
    }

    void del_()
    {
        if (pmodel_)
        {
            delete pmodel_;
            pmodel_ = nullptr;
        }

        if (pview_)
        {
            delete pview_;
            pview_ = nullptr;
        }

    }
};

using stTableModelView	= stTableModelView_;

/// ----------------------------------------------------------------------------------------
/// @brief: 保存tableName
/// ----------------------------------------------------------------------------------------
/// <表名,model_view>
using mapTable		= QMap<QString, stTableModelView>;
-   **mapTable**以表的名称作为key, 将对应表格的数据model和view保存下来

用法范例

/// 2 初始化成功, 显示到界面
const oct_sqlite::mapTable&	map_sqlite_table = psqlite_ext_->map_table_();

/// 3. 表格逐个显示
int index = 0;
for (auto table_it = map_sqlite_table.begin(); table_it != map_sqlite_table.end(); ++table_it)
{
    ui.tabWidget->addTab(table_it->pview_, table_it.key());
    ui.tabWidget->setTabIcon(ui.tabWidget->count() - 1, QIcon(":/png/table.png"));

}

table_

功能

- 读取当前数据库中名为str_table_name的参数

原型

/// -------------------------------------------------------------------------------
/// @brief:		读取当前数据库中名为str_table_name的参数, 
/// @param: 	const QString str_table_name - 读取哪张表
/// @param: 	stTableModelView * pout_tmv - 读取结果存放地址, 内部不会赋值, 外部赋值
///  @ret:		int
///				0 - 成功
///				1 - 失败,参数[pout_tmv]为nullptr
///				2 - 失败, 数据库中没有名为【str_table_name】的表格
/// -------------------------------------------------------------------------------
int table_(const QString str_table_name, stTableModelView* pout_tmv) noexcept;

下面开始介绍数据读写相关函数

table_data_

功能

- 读取str_table_name中的数据到pdata

原型

/// -------------------------------------------------------------------------------
/// @brief:		读取str_table_name中的数据到pdata
/// @param: 	const QString & str_table_name - 哪张表
/// @param: 	void * pdata - 数据存放地址
///  @ret:		int
///				0 - 成功
///				1 - 失败, 参数中的[pdata]为空, 
///				2 - 失败, 参数中【str_table_name】的表没有在当前的数据库中
///				3 - 失败, 无法操作当前表的model
///				5 - 失败, 查询数据库失败
///				6 - 失败, 参数[str_table_name]的表格为空表
///				7 - 失败, 无法获取表格的行数
/// -------------------------------------------------------------------------------
int table_data_(const QString& str_table_name, void* pdata) noexcept;

说明

- 该函数将**str_table_name**表中的数据全部读入到**pdata**的内存中

用法

const int row_count = 2;
st_commom_str st_str[row_count];

/// 执行读取
int ret = common_sql_.table_data_("common", (void*)(&st_str));
for (int index = 0; index < row_count; ++index)
{
    qDebug() << "====================================";
    qDebug() << "index=" << index;
    qDebug() << "id=" << st_str[index].id_;
    qDebug() << "name=" << st_str[index].name_;
    qDebug() << "db=" << st_str[index].db_;
}

table_data_some_columns_

功能

- 读取[str_table_name]表格中指定列的数据

原型

/// -------------------------------------------------------------------------------
/// @brief:		读取表格str_table_name中map_read_column列的数据到pdata中
/// @param: 	const QString & str_table_name - 读取哪张表
/// @param: 	void * pdata - 存放读取结果
/// @param: 	const mapUIntUInt & map_read_column - 那些列需要读取
///  @ret:		int
///				0 - 成功
///				其他 - 失败			
/// -------------------------------------------------------------------------------
int table_data_some_columns_(const QString& str_table_name, void* pdata, const mapUIntUInt& map_read_column) noexcept;

用法

oct_sqlite::mapUIntUInt map_read_column_index;
map_read_column_index.emplace(1, 1);

stTableCommonStr st_common_data;

int read_ret = common_sql_.table_data_some_columns_("common", (void*)&st_common_data, map_read_column_index);
qDebug() << "ret=" << read_ret;

qDebug() << "read_result:\n" << "zs=" << st_common_data.name_zs_ << "\nls=" << st_common_data.name_ls_ << "\n\n------end_commom_-------";

table_data_except_columns_

功能

- 读取表格str_table_name中 不在map_read_column列的数据到pdata中

原型

/// -------------------------------------------------------------------------------
/// @brief:		读取表格str_table_name中 不在map_read_column列的数据到pdata中
/// @param: 	const QString & str_table_name - 哪张表
/// @param: 	void * pdata - 数据存放
/// @param: 	const mapUIntUInt & map_read_column - 那些列不用读取
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
int table_data_except_columns_(const QString& str_table_name, void* pdata, const mapUIntUInt& map_except_column);

用法

oct_sqlite::mapUIntUInt map_except_column_index;

/// 不读取第二列
map_except_column_index.emplace(2, 2);

stTableCommonIdStr st_common_data[2];


int read_ret = common_sql_.table_data_except_columns_("common", (void*)&st_common_data, map_except_column_index);
qDebug() << "ret=" << read_ret;

for (int index = 0; index < 2; ++index)
{
    qDebug() << "id=" << st_common_data[index].id_ << ", name=" << st_common_data[index].name_zs_;
}

submit_

功能

- 初始化参数指定为: ES_MANUAL_SUBMIT , 调用该函数将界面输入写入文件

原型

/// -------------------------------------------------------------------------------
/// @brief:		初始化参数指定为: ES_MANUAL_SUBMIT , 调用该函数
/// @param: 	const QString & str_table_name - 哪张表需要提交
///  @ret:		int
///				0 - 成功
///				1 - 失败, 没有找到
///				2 - 失败,没有对应的model
///				3 - 失败, 提交失败
/// -------------------------------------------------------------------------------
int submit_(const QString& str_table_name) noexcept;

用法

int ret = psqlite_ext_->submit_(str_table_name);

QString str_hint;
if (0 != ret)
{
    str_hint = tr("failed to submit");
}
else
{
    str_hint = tr("succeed to submit");
}

table_data_map_

功能

- 将表格中的数据全部读入map中,其中,map的key就是表格的主键

原型

/// -------------------------------------------------------------------------------
/// @brief:		读取【str_table_name】中的数据,将结果存放到[pout_map]中
/// @param: 	const QString str_table_name - 哪张表
/// @param: 	std::map<TKey,TValue> * pout_map - 存放表数据的map, 外部分配空间, 函数内仅仅赋值,
/// @param: 	const int ui_key_column_index - map的TKey所在列, 从0开始数
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
template<class TKey, class TValue>
int table_data_map_(const QString str_table_name, std::map<TKey, TValue>* pout_map, const int ui_key_column_index) noexcept;

用法

/// 执行读取
std::map<int, udp_channel> map_udp_channel;
int ret = common_sql_.table_data_map_<int, udp_channel>("udp_channel", &map_udp_channel, 0);

int map_count			= map_udp_channel.size();
for (std::map<int, udp_channel>::iterator find_it = map_udp_channel.begin(); find_it != map_udp_channel.end(); ++find_it)
{
    qDebug() << "====================================";
    qDebug() << "id=" << find_it->second.id_ <<", name=" << find_it->second.name_ << ", dest_ip=" << find_it->second.dest_ip_ << ", dest_port=" << find_it->second.dest_ip_;
    ++find_it->second.port_;
}

table_data_map_some_columns_

功能

- 只读取map_read_column_index列中的数据到pdata中

原型

/// -------------------------------------------------------------------------------
/// @brief:		只读取map_read_column_index列中的数据到pdata中
/// @param: 	const QString str_table_name - 读取哪张表
/// @param: 	std::map<TKey,TValue> * pout_map - 用于读取内容存放
/// @param: 	const int ui_key_column_index - 主键再第几列, 从0开始数
/// @param: 	const mapUIntUInt & map_read_column_index - 读取表格的哪些列, 从0开始数
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
template<class TKey, class TValue>
int table_data_map_some_columns_(const QString str_table_name, std::map<TKey, TValue>* pout_map, const int ui_key_column_index, const mapUIntUInt& map_read_column_index) noexcept;

table_data_map_except_columns_

功能

- 读取不在map_read_column_index列中的数据到pdata中

原型


/// -------------------------------------------------------------------------------
/// @brief:		读取不在map_read_column_index列中的数据到pdata中
/// @param: 	const QString str_table_name - 读取哪张表
/// @param: 	std::map<TKey,TValue> * pout_map - 用于读取内容存放
/// @param: 	const int ui_key_column_index - 主键再第几列, 从0开始数
/// @param: 	const mapUIntUInt & map_read_column_index - 不读取表格的哪些列, 从0开始数
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
template<class TKey, class TValue>
int table_data_map_except_columns_(const QString str_table_name, std::map<TKey, TValue>* pout_map, const int ui_key_column_index, const mapUIntUInt& map_read_except_column_index) noexcept;

update_table_

功能

- 将数据写入数据库,注意: pdata中的行数应该与数据库中表的数据相同,否则,将返回非0

原型

/// -------------------------------------------------------------------------------
/// @brief:		将数据写入数据库,注意: pdata中的行数应该与数据库中表的数据相同,否则,将返回非0
/// @param: 	const QString str_table_name - 哪张表
/// @param: 	void * pdata - 带写入数据的起始地址
/// @param: 	const uint key_index - 主键在哪一列,从0 开始数, 
///  @ret:		int
///				0 - 成功
///				1 - 失败, 参数pdata为空
///				2 - 失败, 无法获取对应表
/// -------------------------------------------------------------------------------
int update_table_(const QString str_table_name, void* pdata, const uint key_index) noexcept;

用法

qDebug() << "================   read_table  AAAAAA	====================";
const int row_count = 2;
st_commom_str st_str[row_count];

/// 执行读取
int ret = common_sql_.table_data_("common", (void*)(&st_str));
for (int index = 0; index < row_count; ++index)
{
    qDebug() << "====================================";
    qDebug() << "index=" << index;
    qDebug() << "id=" << st_str[index].id_;
    qDebug() << "name=" << st_str[index].name_;
    qDebug() << "db=" << st_str[index].db_;
}

/// write
st_str[0].db_ = 1122.0f;
st_str[1].db_ = 5566.0f;


ret = common_sql_.update_table_("common", &st_str, 0);
qDebug() << "\n\n update_result=" << ret << "\n\n";

update_table_some_columns_

功能

- 只更新map_update_column_index中的列到数据库

原型

/// -------------------------------------------------------------------------------
/// @brief:		只更新map_update_column_index中的列到数据库
/// @param: 	const QString str_table_name - 更新哪张表
/// @param: 	void * pdata - 待写入的数据
/// @param: 	const uint key_index - 表格的主键再第几列,从0开始数
/// @param: 	const mapUIntUInt map_update_column_index - 要写入那些列
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
int update_table_some_columns_(const QString str_table_name, void* pdata, const uint key_index, const mapUIntUInt map_update_column_index) noexcept;

update_table_except_columns_

功能

- 只更新不在map_update_column_index中的列到数据库  

原型

/// -------------------------------------------------------------------------------
    /// @brief:		只更新不在map_update_column_index中的列到数据库
    /// @param: 	const QString str_table_name - 更新哪张表
    /// @param: 	void * pdata - 待写入的数据
    /// @param: 	const uint key_index - 表格的主键再第几列,从0开始数
    /// @param: 	const mapUIntUInt map_update_column_index - 不写入那些列
    ///  @ret:		int
    ///				0 - 成功
    ///				其他 - 失败	
    /// -------------------------------------------------------------------------------
    int update_table_except_columns_(const QString str_table_name, void* pdata, const uint key_index, const mapUIntUInt map_except_column_index) noexcept;

update_table_map_

功能

- 将pmap_data中的数据写入[str_table_name]中, 注意: pmap_data中的行数应该与数据库中表的数据相同,否则,将返回6

原型

/// -------------------------------------------------------------------------------
/// @brief:		将pmap_data中的数据写入[str_table_name]中, 注意: pmap_data中的行数应该与数据库中表的数据相同,否则,将返回6
/// @param: 	const QString str_table_name - 对应书库中表的名字
/// @param: 	const std::map<TKey, TValue> * pmap_value - 待写入数据内容
/// @param: 	const uint key_column_index - str_table_name的主键在哪一列, 从0 开始数
///  @ret:		int
///				
/// -------------------------------------------------------------------------------
template<typename TKey, typename TValue>
int update_table_map_(const QString str_table_name, const std::map<TKey, TValue>* pmap_data, const uint key_column_index) noexcept;

update_table_map_some_columns_

功能

- 将map_update_column_index中的数据写入[str_table_name]中, 且只写入【map_update_column_index】中的列数据,

原型

/// -------------------------------------------------------------------------------
/// @brief:		将map_update_column_index中的数据写入[str_table_name]中, 且只写入【map_update_column_index】中的列数据,
/// @param: 	const QString str_table_name - 对应书库中表的名字
/// @param: 	const std::map<TKey, TValue> * pmap_value - 待写入数据内容
/// @param: 	const uint key_column_index - str_table_name的主键在哪一列, 从0 开始数
/// @param: 	const mapUIntUInt map_update_column_index - 要写入哪些列的数据
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
template<typename TKey, typename TValue>
int update_table_map_some_columns_(const QString str_table_name, const std::map<TKey, TValue>* pmap_data, const uint key_column_index, const mapUIntUInt& map_update_column_index) noexcept;

update_table_map_except_columns_

功能

- 将不在map_except_column_index中的数据写入[str_table_name]中, 且只写入【map_update_column_index】中的列数据,

原型

/// -------------------------------------------------------------------------------
/// @brief:		将不在map_except_column_index中的数据写入[str_table_name]中, 且只写入【map_update_column_index】中的列数据,
/// @param: 	const QString str_table_name - 对应书库中表的名字
/// @param: 	const std::map<TKey, TValue> * pmap_value - 待写入数据内容
/// @param: 	const uint key_column_index - str_table_name的主键在哪一列, 从0 开始数
/// @param: 	const mapUIntUInt map_update_column_index - 不要写入哪些列的数据
///  @ret:		int
///				0 - 成功
///				其他 - 失败
/// -------------------------------------------------------------------------------
template<typename TKey, typename TValue>
int update_table_map_except_columns_(const QString str_table_name, const std::map<TKey, TValue>* pmap_data, const uint key_column_index, const mapUIntUInt& map_except_column_index) noexcept;

下面是一些其他支撑函数

file_suffix_is_right_

功能

- 检查参数中的后缀是否为支持的后缀

原型

/// -------------------------------------------------------------------------------
/// @brief:		检查文件后缀是否为可支持类型
/// @param: 	const QString & str_suffix - 待检查的文件后缀
///  @ret:		bool
///				true - 支持, 
///				false - 不支持
/// -------------------------------------------------------------------------------
bool file_suffix_is_right_(const QString& str_suffix) noexcept;

suffix_

功能

- 获取支持的文件后缀字符串

原型

/// -------------------------------------------------------------------------------
/// @brief:		将支持的文件以字符串的形式返回
///  @ret:		QT_NAMESPACE::QString	
/// -------------------------------------------------------------------------------
QString suffix_() noexcept;

完整范例

- 下一节开启
posted @ 2022-03-23 23:19  mohist  阅读(253)  评论(0编辑  收藏  举报