zethika / virtual-sql
MySQL 的基于类的抽象层,旨在帮助以编程方式编写 MySQL 查询。
Requires
- php: >=8.0
- ext-mbstring: *
- ext-pdo: *
- dev-master
- v1.7.1
- v1.7.0
- v1.6.6
- v1.6.5
- v1.6.4
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.0
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feature/add-automatic-testing
This package is auto-updated.
Last update: 2024-09-28 08:32:02 UTC
README
Virtual SQL 是一个基于类的 MySQL 抽象层,旨在帮助以编程方式编写 MySQL 查询。
它允许通过单个 VirtualSqlQuery 类与查询结构交互,将实际的 MySQL 语法抽象化。
安装
composer require zethika/virtual-sql
表定义
Virtual SQL 提供了一个名为 VirtualSqlTable 的类,用于定义数据库表及其列,当与这些表交互查询时需要使用它。
这些表定义可以在运行时生成,通过将 PDO 实例提供给 VirtualSqlTableDefinitionGenerator 单例。
然后可以直接从数据库提取 CREATE TABLE 定义,并提供一个表示给定表的实例。
从数据库提取的 CREATE TABLE 语句保留在内存中,以减少对同一表的重复调用产生的多余 SQL 查询。
use VirtualSql\Generator\VirtualSqlTableDefinitionGenerator;
try {
$pdo = new PDO('mysql:host='.$_ENV['DB_HOST'].';dbname='.$_ENV['DB_NAME'], $_ENV['DB_USER'], $_ENV['DB_PASS']);
$pdo->exec("SET NAMES utf8");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
trigger_error($e->getMessage(),E_USER_ERROR);
}
$generator = VirtualSqlTableDefinitionGenerator::getInstance();
$generator->init($pdo);
// A VirtualSql\Definition\VirtualSqlTable instance
$tableDefinition = $generator->generateTableDefinition('table_name');
查询
查询是通过 VirtualSqlQuery 的子类构建的,是程序接口,运行时通过它构建查询。
它们提供了一系列辅助函数,根据正在构建的查询类型,以便更容易地操作查询部分。
可以通过向 VirtualSqlQuery::factory 方法提供一个类型常量和一个基础表的 VirtualSqlTable 实例来生成查询实例。
支持的类型有 TYPE_SELECT、TYPE_INSERT、TYPE_UPDATE 和 TYPE_DELETE
use VirtualSql\Query\VirtualSqlQuery;
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_SELECT,$table);
查询配置参数
可以向工厂方法提供一个第三个参数,一个关联数组 $config。
这可以用来在实例化时设置查询的大部分值。
可能的键取决于特定的查询类型。通过 $config 参数设置的值也可以在实例化后通过方法调用进行操作。
SELECT
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_SELECT,$table, [
// Array of VirtualSqlColumn instances, describing which columns to select
'selects' => [
$table->getColumn('some_column'),
$table->getColumn('another_column')
],
// Array of VirtualSqlJoin instances, describing which joins to perform
// It's recommended using the query helper methods instead
'joins' => [
new VirtualSqlJoin($fromColumn, $toColumn)
],
// VirtualSqlConditionSet instance representing the base condition set
'where' => new VirtualSqlConditionSet(VirtualSqlConstant::OPERATOR_AND, $conditions),
// int|null representing the LIMIT parameter
'limit' => 10,
// int|null representing the OFFSET parameter
'offset' => 10
]);
INSERT
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_INSERT,$table, [
// Array of VirtualSqlColumn instances, describing which columns to insert into
'columns' => $table->getColumns(),
// Array of associative arrays describing the value sets being inserted
'valueSets' => [
[
'column_1' => 'some_value',
'column_2' => 'some_value,
],
[
'column_1' => 'some_value',
'column_2' => 'some_value,
]
],
// Array of VirtualSqlColumn instances, describing which columns should be updated in the ON DUPLICATE KEY UPDATE part
// If none are provided, this query part will not be generated
'onDuplicateUpdateColumns' => [
$uuidTable->getColumn('blog_id'),
$uuidTable->getColumn('resource_id'),
]
]);
UPDATE
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_UPDATE,$table, [
// Array of VirtualSqlColumn instances, describing which columns to update
'columns' => $table->getColumns(),
// Associative array describing the values being updated
'values' => [
'column_1' => 'some_value',
'column_2' => 'some_value,
],
// Array of VirtualSqlJoin instances, describing which joins to perform
// It's recommended using the query helper methods instead
'joins' => [
new VirtualSqlJoin($fromColumn, $toColumn)
],
// VirtualSqlConditionSet instance representing the base condition set
'where' => new VirtualSqlConditionSet(VirtualSqlConstant::OPERATOR_AND, $conditions),
]);
DELETE
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_DELETE,$table, [
// Array of VirtualSqlJoin instances, describing which joins to perform
// It's recommended using the query helper methods instead
'joins' => [
new VirtualSqlJoin($fromColumn, $toColumn)
],
// VirtualSqlConditionSet instance representing the base condition set
'where' => new VirtualSqlConditionSet(VirtualSqlConstant::OPERATOR_AND, $conditions),
// int|null representing the LIMIT parameter
'limit' => 10,
]);
完整示例
<?php
use VirtualSql\Generator\VirtualSqlTableDefinitionGenerator;
use VirtualSql\Query\VirtualSqlQuery;
use VirtualSql\QueryParts\VirtualSqlConditionSetBuilder;
require_once __DIR__.'/vendor/autoload.php';
try {
$pdo = new PDO('mysql:host='.$_ENV['DB_HOST'].';dbname='.$_ENV['DB_NAME'], $_ENV['DB_USER'], $_ENV['DB_PASS']);
$pdo->exec("SET NAMES utf8");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
trigger_error($e->getMessage(),E_USER_ERROR);
}
$generator = VirtualSqlTableDefinitionGenerator::getInstance();
$generator->init($pdo);
$table1 = $generator->generateTableDefinition('table_name');
$table2 = $generator->generateTableDefinition('another_table_name');
$query = VirtualSqlQuery::factory(VirtualSqlQuery::TYPE_SELECT,$table1);
// Adding an INNER JOIN statement, with a multidimensional condition on it.
$query->innerJoin(
$table1->getColumn('id'),
$table2->getColumn('table1_id'),
$query->andX(
$query->condition($table1->getColumn('some_column'),'?'),
$query->condition($table1->getColumn('another_column'),'?'),
$query->orX(
$query->condition($table2->getColumn('a_third_column'),'?'),
$query->condition($table2->getColumn('a_fourth_column'),'?')
)
)
);
// Add an additional, seperate where statement
$query->addWhere($query->andX(
$query->condition($table2->getColumn('second_table_column'),'some_value'),
$query->condition($table1->getColumn('another_table_column'),'some_other_value')
));
// Define the selects by referencing specific columns via their table instance.
// If no selects are defined or this method is never called, "*" is the default
$query->setSelects(
[
$table1->getColumn('id'),
$table2->getColumn('the_value_column_on_second_table')
]
);
// The actual SQL query string
$sql = $query->getSql();
// An associative array of all the named parameters used in the SQL
$parameters = $query->getNamedParameters();
辅助工具
根据正在处理的 VirtualSqlQuery 类型,实例上存在多个辅助方法来添加/操作各种部分。
例如,为了在 SELECT 查询上创建连接,有 "innerJoin"、"leftJoin"、"rightJoin" 和 "outerJoin" 方法,它们接受一个 $from & $to 列,以及可选的条件集
条件
Virtual SQL 使用 VirtualSqlCondition 实例来描述单个条件,使用 VirtualSqlConditionSet 来描述条件集。
为了帮助构建它们,VirtualSqlQuery 有 3 个辅助方法 "andX"、"orX" 和 "condition","andX" 和 "orX" 接受任意数量的参数,这些参数是 VirtualSqlCondition 或 VirtualSqlConditionSet。
$conditionSet = $query->andX(
$query->condition($table1->getColumn('some_column'),'?'),
$query->condition($table1->getColumn('another_column'),'?'),
$query->orX(
$query->condition($table2->getColumn('a_third_column'),'?'),
$query->condition($table2->getColumn('a_fourth_column'),'?')
)
)
实例化后,条件仍然可以操作和添加/删除,正如预期的那样。