按执行顺序出现的问题

时间:2018-07-03 12:58:08

标签: c++

我的数据库请求者的顺序顺序有些问题。

给出以下示例:

请求者具有数据库连接和QueryBuilder,后者负责创建数据库查询。 这些查询可以由请求者执行。

为了支持转义输入参数,QueryBuilder需要一个指向数据库事务的指针。 该指针将在构造函数中设置。

QueryBuilder是Requester类的成员,因此我们必须在Requester的构造函数中设置Transaction。 但是目前,数据库连接(+事务)尚未初始化(将在run()方法中初始化)。

我的问题出现在下面的代码中:

class QueryBuilder
{

public:

    QueryBuilder(const DbTransaction* const dbTransaction)
        : _dbTransaction(dbTransaction)
    {
    }

    std::string QueryBuilder::getSelect(const std::string& key) const
    {
        return "SELECT a, b, c FROM table WHERE key = '" + dbTransaction->escape(key) + "';";
    }

private:

    const DbTransaction* const _dbTransaction;
}


class Requester
{

public:

    Requester()
        : _queryBuilder(_dbConnection->getTransaction())              // Here _dbConnection is not initialized
                                                                      // The -dbConnection->transaction pointer will be initialized in beginTransaction();
    {
    }

    ~Requester()
    {
    }

    void run()
    {
        _dbConnection.openDatabase();
        _dbConnection.beginTransaction();

        // iterate over records and call for every record:
        importRecordByKey(key);

        _dbConnection.commitTransaction();
        _dbConnection.closeDatabase();
    }

    void importRecordByKey(const std::string& key)
    {
        DbResult result = _dbConnection.executeQuery(_queryBuilder.getSelect(key));
        // do something with result
    }
}

private:

    DbConnection _dbConnection;
    QueryBuilder _queryBuilder;

处理此问题的最佳方法是什么?

我可能的解决方案是:

  1. 不要将queryBuilder用作成员,只需在run()方法中创建一个即可。 但这对性能根本没有好处,因为每条记录都会创建并破坏QueryBuilder。 对于100000条以上的记录,我会花一些时间?!

示例:

void importRecordByKey(const std::string& key)
{
  QueryBuilder qb(_dbConnection.getTransaction());
  DbResult result = _dbConnection.executeQuery(qb.getSelect(key));
  // do something with result
}   
  1. 为queryBuilder成员使用一个指针。因此,在创建dbconnection / transaction之后,我可以初始化查询生成器

示例(带有shared_ptr):

void importRecordByKey(const std::string& key)
{
  if(!_queryBuilder)
  {
    _queryBuilder(new QueryBuilder(_dbConnection.getTransaction()));
  }

  DbResult result = _dbConnection.executeQuery(_queryBuilder.getSelect(key));
  // do something with result
}

1 个答案:

答案 0 :(得分:0)

importRecordByKey()是否需要公开?如果没有,那怎么办?

class QueryBuilder
{
public:
    QueryBuilder(const DbTransaction* const dbTransaction)
        : _dbTransaction(dbTransaction)
    {
    }

    std::string QueryBuilder::getSelect(const std::string& key) const
    {
        return "SELECT a, b, c FROM table WHERE key = '" + dbTransaction->escape(key) + "';";
    }

private:
    const DbTransaction* const _dbTransaction;
}


class Requester
{
public:
    Requester()
    {
    }

    ~Requester()
    {
    }

    void run()
    {
        _dbConnection.openDatabase();
        _dbConnection.beginTransaction();
        QueryBuilder qB(_dbConnection->getTransaction());

        // iterate over records and call for every record:
        importRecordByKey(key, qB);

        _dbConnection.commitTransaction();
        _dbConnection.closeDatabase();
    }

private:
    void importRecordByKey(const std::string& key, const QueryBuilder& qB)
    {
        DbResult result = _dbConnection.executeQuery(qB.getSelect(key));
        // do something with result
    }

    DbConnection _dbConnection;
}