programster/multi-query

mysqli 的包装对象,可以将查询组合成一个。

3.0.0 2023-10-24 12:15 UTC

This package is auto-updated.

Last update: 2024-09-24 17:51:02 UTC


README

这是一个简化在单个请求中发送多个 PHP Mysqli 查询并处理响应的包。这通常通过去除往返时间来显著提高性能,尤其是在数据库位于远程主机时。

示例用法

基本示例

$db = new mysqli($host, $user, $password, $db_name);

$queries = array(
    "DROP TABLE `table1`",
    "DROP TABLE `table2`",
    "DROP TABLE `table3`"
);

$multiQuery = new Programster\MultiQuery\MultiQuery($db, $queries);

完整示例

在下面的示例中,我们执行了大量的不同查询,并使用我们在添加查询时获得的索引来稍后从 multiQuery 对象中获取其结果。我们还演示了如何通过检查对象运行后的状态来检查是否一切正常。

$connection = new mysqli('host', 'user', 'password', 'db_name');

$queries = array(
    'SELECT * FROM `table1`',
    'SHOW TABLES`',
    'SELECT * FROM `table2`'
);

$select1QueryIndex = 0;
$showTablesQueryIndex = 1;
$select2QueryIndex = 2;

$multiQuery = new Programster\MultiQuery\MultiQuery($connection, $queries);


if ($multiQuery->hasErrors())
{
    $errors = $multiQuery->getErrors();
    // do something with the errors array such as use them in an
    // exception message....
}
else
{
    $tablesResult = $multiQuery->getResult($showTablesQueryIndex);

    if ($tablesResult === FALSE)
    {
        throw new Exception("Failed to fetch tables");
    }
    else
    {
        $tables = array();

        while (($row = $tablesResult->fetch_array()) !== null)
        {
            $tables[] = $row[0];
        }

        print "tables: " . implode(", ", $tables);
    }
}

合并结果示例

如果您使用单独的表(例如,所有表都具有相同的结构)对数据进行分区,那么您可能想使用 get_merged_result() 方法将所有查询结果简单地拼接在一起。

# // Example 2 - Fetch data from two tables that have exactly the same structure
# // e.g. a case of partitioning data using table names like "dataset1", "dataset2"

$queries = array(
    'SELECT * FROM `table1`',
    'SELECT * FROM `table2`'
);

$multiQuery2 = new Programster\MultiQuery\MultiQuery($connection, $queries);
$mergedResult = $multiQuery2->getMergedResult();
print "merged result: " . print_r($mergedResult, true) . PHP_EOL;

事务

此包还包括一个用于帮助进行 MySQL 事务的类。以下是使用此类的示例。

$queries = array(
    'DELETE FROM `myTable` WHERE id = ' . $id,
    'INSERT INTO `myTable` SELECT * FROM `myTable2` WHERE id = ' . $id
);

$transaction = new Programster\MultiQuery\Transaction($mysqli, $queries);

if (!$transaction->wasSuccessful())
{
    throw new Exception("Failed to reset the record in xyz");
}

如果事务对象中的 任何 查询失败,事务将自动检测并回滚。默认情况下,如果事务失败,对象将不会重试,但您可以将它配置为这样做。以下是相同的示例,但这次我们将它设置为在执行事务时重试最多 5 次,并且每次尝试之间等待 3 秒。如果您没有设置它,则默认的睡眠时间为 1 秒。

$queries = array(
    'DELETE FROM `myTable` WHERE id = ' . $id,
    ... # more quries here.
);

$transaction = new Programster\MultiQuery\Transaction(
    $mysqli,
    $queries,
    $attempts=5,
    $sleepPeriod=3
);
...