案例:

声明:

/**
* @brief 定义了访问数据库算法的骨架,SQL 语句执行的结果使用传进来的 Lambda 表达式处理
* @param sql sql语句
* @param params 参数
* @param fn 处理 SQL 语句执行的结果的 Lambda 表达式
*/
static void executeSql(const QString &sql, const QVariantMap &params, std::function<void(QSqlQuery *query)> handleResult);

实现:

void DbUtil::executeSql(const QString &sql, const QVariantMap &params, std::function<void (QSqlQuery *)> handleResult)
{
QSqlDatabase db = Singleton<ConnectionPool>::getInstance().openConnection();
QSqlQuery query(db);
query.prepare(sql);
bindValues(&query, params);

if (query.exec()) {
handleResult(&query);
}

debug(query, params);
Singleton<ConnectionPool>::getInstance().closeConnection(db);
}

void DbUtil::bindValues(QSqlQuery *query, const QVariantMap &params)
{
for (QVariantMap::const_iterator i=params.constBegin(); i!=params.constEnd(); i++) {
query->bindValue(":" + i.key(), i.value());
}
}

std::function<void(QSqlQuery *query)> handleResult:
void(QSqlQuery *query):返回类型 (参数声明)

使用

int DbUtil::insert(const QString &sql, const QVariantMap &params)
{
int id = -1;
//id 是引用传递
executeSql(sql, params, [&id](QSqlQuery *query){
//插入行的主键
id = query->lastInsertId().toInt();
});
return id;
}

bool DbUtil::update(const QString &sql, const QVariantMap &params)
{
bool result;
executeSql(sql, params, [&result](QSqlQuery *query){
result = query->lastError().type() == QSqlError::NoError;
});
return result;
}
QVariant DbUtil::selectVariant(const QString &sql, const QVariantMap &params)
{
QVariant result;
executeSql(sql, params, [&result](QSqlQuery *query){
if (query->next()) {
result = query->value(0);
}
});
return result;
}

QList<QVariantMap> DbUtil::selectMaps(const QString &sql, const QVariantMap &params)
{
QList<QVariantMap> rowMaps;
executeSql(sql, params, [&rowMaps](QSqlQuery *query){
rowMaps = queryToMaps(query);
});
return rowMaps;
}

QList<QVariantMap> DbUtil::queryToMaps(QSqlQuery *query)
{
QList<QVariantMap> rowMaps;
QStringList fieldNames = getFieldNames(query);
while (query->next()) {
QVariantMap rowMap;
for (const QString fieldName : fieldNames) {
rowMap.insert(fieldName, query->value(fieldName));
}
rowMaps.append(rowMap);
}
return rowMaps;
}
QStringList DbUtil::getFieldNames(const QSqlQuery &query)
{
QSqlRecord record = query.record();
QStringList names;
for (int i=0; i<record.count(); i++) {
names << record.fieldName(i);
}
return names;
}