Drogon中视图展示获取Sqlite中的数据

起因

今天我说Drogon如何从Sqlite获取数据,Drogon提供了两种方式,第一种方式就是通过sql查询,第二种提供了ORM将结果返回到实体中.

使用Sql查询

void HomeController::test(
    const HttpRequestPtr &req,
    std::function<void(const HttpResponsePtr &)> &&callback) {

  // 获取数据库客户端指针
  auto dbClientPtr = drogon::app().getDbClient();

  // 执行sql同步获取结果
  // dbClientPtr->execSqlSync();

  // 异步执行sql
  auto dbResult = dbClientPtr->execSqlAsyncFuture("SELECT * FROM Articles");
   
  try {

    auto result = dbResult.get(); // 获取查询结果

    cout << result.size() << endl; // 获取结果的条数
    for (auto row : result) {      // 循环执行 打印查询到的结果
      cout << "id: " << row["id"].as<int>()
           << "title: " << row["title"].as<string>()
           << "content: " << row["content"].as<string>()
           << "fileName: " << row["fileName"].as<string>() << endl;
    }
  } catch (const std::exception &e) {
    cout << e.what() << endl;
  }

  auto resp = HttpResponse::newHttpResponse();
  resp->setBody("ok");
  callback(resp);
}

打印从Sqlite获取的数据

使用Drogon提供的ORM,将获取到的实体在CSP中展示

void HomeController::get(
    const HttpRequestPtr &req,
    std::function<void(const HttpResponsePtr &)> &&callback, std::string page) {

  // HttpViewData是用来存放数据,在CSP中使用
  HttpViewData data;

  int pageIndex = 1;
  if (!page.empty()) {
    // 页码 进行类型转换
    pageIndex = std::stoi(page);
  }

  // 获取数据库客户端指针
  auto dbClientPtr = drogon::app().getDbClient();
  try {
    // 通过Mapper映射实体
    Mapper<Articles> articlesMapper(dbClientPtr);
    auto articleList =
        articlesMapper.orderBy(Articles::Cols::_Id, SortOrder::DESC)
            .limit(20)
            .offset((pageIndex - 1) * 20)
            .findAll();
    // 将查询到实体列表放入viewData中
    data.insert("articles", articleList);

    // 映射文章类别,并放入viewData
    Mapper<Categories> categoriesMapper(dbClientPtr);
    auto categoryList = categoriesMapper.findAll();
    data.insert("categoryList", categoryList);

    // 生成分页标签
    string links = pageLink(400, 20, pageIndex, "");
    data.insert("pageLink", links);

  } catch (const std::exception &e) {
    cout << e.what() << endl;
  }

  // 使用CSP模板
  auto resp = HttpResponse::newHttpViewResponse("HomeIndex", data);
  callback(resp);
}

如何使用CSP模板

<%inc#include "Articles.h"      //引入文章列表
    #include "Categories.h"%>   //引入文章类别列表
    <%c++
    auto articleList = @@.get
    <std::vector<drogon_model::sqlite3::Articles>>("articles");  //从HttpViewData获取文章列表
        auto categoryList = @@.get<std::vector<drogon_model::sqlite3::Categories>>("categoryList"); //从HttpViewData获取文章列表
%>

如何展示文件列表:

<%c++ for(auto article:articleList){%>
<div class="post-item">
    <div class="caption wrapper-lg">
        <h2 class="post-title">
            <a href="/articles/{% *(article.getFilename())%}">{% *article.getTitle()%}</a>
        </h2>
        <div class="post-sum">
            {% *article.getAbout()%}
        </div>
        <div class="line line-lg"></div>
        <div class="text-muted">
            <i class="fa fa-user icon-muted"></i>来自 <a href="#" class="m-r-sm">秋风</a>
            <i class="fa fa-clock-o icon-muted"></i>
            {% *article.getShowtime()%}
        </div>
    </div>
</div>
<%c++}%>

在csp模板中展示实体

效果

目前还是和使用Asp.Net Core一样的样式,周末只实现这些功能,后面再说一下生成分页标签,主要这一块第一次实现,感觉不是很高效.
使用Drogon实现博客首页
秋风 2023-02-01