nguyenzz / design-patterns
v1.1
2024-08-07 09:22 UTC
README
1. 构建者设计模式
构建者模式是一种创建型模式,它允许您按步骤构建复杂对象。该模式允许您使用相同的代码创建不同类型和表现的对象。
例如:考虑如何创建房屋对象。要构建一栋简单的房子,你需要建造四面墙和一层,安装门和窗,然后建造屋顶。但如果你想要一个更大、更明亮的房子,有后院和其他设施(如供暖系统、水管和电线系统)呢?
最简单的解决方案是扩展基本House类,并创建一个包含所有参数组合的子类集。但最终你将拥有大量的子类。任何新的参数,比如门廊类型,都会要求进一步开发这个分级系统。
有一种不涉及子类继承的方法。你可以在基本House类中创建一个巨大的构造函数,包含所有可能的参数以控制house对象。尽管这种方法实际上消除了对子类的需求,但它又带来了另一个问题。
例如:Builder接口声明了一组方法来组装MySQL查询。所有的构建步骤都返回构建器对象本身,以允许链式调用:$ builder->select(...) -> where(...)
<?php
namespace Nguyen\DesignPatterns;
interface SQLQueryBuilder
{
public function execinsert(string $table, array $data): SQLQueryBuilder;
public function execselect(string $table, array $columns): SQLQueryBuilder;
public function execwhere(string $column, string $value): SQLQueryBuilder;
public function execorwhere(string $column, string $value, string $operator = '='): SQLQueryBuilder;
public function execnotwhere(string $column, string $value, string $operator = '='): SQLQueryBuilder;
public function execorderby(array $data): SQLQueryBuilder;
public function execfind(string $table, int $id): SQLQueryBuilder;
public function execupdate(string $table, array $data): SQLQueryBuilder;
public function execdelete(string $table, string $column, string $value): SQLQueryBuilder;
public function execlimit(int $start, int $offset): SQLQueryBuilder;
public function execin(string $column, array $data): SQLQueryBuilder;
public function execjoins(string $table, string $join, string $column1, string $column2): SQLQueryBuilder;
public function execfirst(): SQLQueryBuilder;
public function exec_alteradd(string $table, string $column, string $data_type): SQLQueryBuilder;
public function exec_alterdrop(string $table, string $column): SQLQueryBuilder;
public function exec_altermodify(string $table, string $column, string $data_type): SQLQueryBuilder;
public function exec_rename(string $table, string $newname): SQLQueryBuilder;
public function execgetSQL(): string;
public function executeQuery(): array;
public function executeAlterQuery(): bool;
}
每个具体Builder对应于MySQL的一个特定方言,并且可以稍微修改构建步骤。
<?php
namespace Nguyen\DesignPatterns;
class MysqlQueryBuilder implements SQLQueryBuilder
{
protected $query;
protected $table;
public function __construct()
{
$this->query = new \stdClass();
$this->query->select = "*";
}
public function __call(string $name, array $arguments)
{
return $this->{"exec" . $name}(...$arguments);
}
public static function __callStatic(string $name, array $arguments)
{
return (new static)->{"exec" . $name}(...$arguments);
}
public function exectable(string $table): self
{
$this->query->table = $table;
$this->query->type = 'select';
return $this;
}
public function execgetSQL(): string
{
$query = $this->query;
$sql = "SELECT " . $this->query->select . " FROM " . $this->query->table;
if (!empty($query->where)) {
$sql .= " WHERE " . implode(' AND ', $query->where);
}
if (!empty($query->orwhere)) {
$sql .= " OR " . implode(' OR ', $query->orwhere);
}
if (!empty($query->notwhere)) {
$sql .= " WHERE NOT" . implode(' AND NOT', $query->notwhere);
}
if (isset($query->limit)) {
$sql .= $query->limit;
}
if (isset($query->order)) {
$sql .= $query->order;
}
$sql .= ";";
return $sql;
}
public function executeQuery(): array
{
$sql = $this->execgetSQL();
print_r($sql);
$db = new Database();
try {
$qr = $db->connect('localhost', 'root', 'abc1234', 'BT')->query($sql);
} catch (\PDOException $e) {
echo "Error executing query: " . $e->getMessage();
return [];
}
$ar = [];
while ($row = $qr->fetch(\PDO::FETCH_ASSOC)) {
$ar[] = $row;
}
return $ar;
}
}
下面是如何使用
<?php
require './vendor/autoload.php';
use Nguyen\DesignPatterns\MysqlQueryBuilder;
use Nguyen\DesignPatterns\Database;
$result = MysqlQueryBuilder::select(["id", "city_name", "country_id", "population"])->executeQuery();
print_r($result);
结果
如何使用PHP包
安装
composer require nguyenzz/design-patterns:dev-main
基本使用方法
1. 使用composer自动加载器
require "../vendor/autoload.php";
use Nguyen\DesignPatterns\Database;
use Nguyen\DesignPatterns\MysqlQueryBuilder;
2. 设置数据库连接
$db = Database::connect(string $hostname, string $username, string $password, string $dbname);
3. 使用查询构建器
-
获取"city"表的全部数据
$result = MysqlQueryBuilder::table("city")->executeSelectQuery(); print_r($result);
-
获取"city"表的"id"和"city_name"列的数据
$result = MysqlQueryBuilder::table("city")->select(["id", "city_name"])->executeSelectQuery(); print_r($result);
-
查找"city"表中城市名称的数量
$result = MysqlQueryBuilder::table("city")->count("id")->executeSelectQuery(); print_r($result);
-
向"city"表中添加数据
$result = MysqlQueryBuilder::insert("city", ["6", "nguyen", "2", "453534"])->executeSelectQuery(); print_r($result);
-
在"city"表中查找数据值
$result = MysqlQueryBuilder::table("city")->where("city_name", "Hà Nội")->executeSelectQuery(); print_r($result);
-
修改"city"表中的数据
$result = MysqlQueryBuilder::update("city", ["id"=>"6", "city_name"=>"nguyen", "country_id" => "2", "population" => "323432"])->executeQuery(); print_r($result);
-
限制从"city"表中返回的数据
$result = MysqlQueryBuilder::table("city")->limit(1, 3)->executeSelectQuery(); print_r($result);
-
向"city"表中添加列
$result = MysqlQueryBuilder::_alteradd("city", "acreage", "int")->executeAlterQuery(); print_r($result);
-
从"city"表中删除列
$result = MysqlQueryBuilder::_alterdrop("city", "acreage")->executeAlterQuery(); print_r($result);
-
修改"city"表中的列
$result = MysqlQueryBuilder::_altermodify("city", "acreage", "int")->executeAlterQuery(); print_r($result);
-
检查"city"表中数据的存在性
$result = MysqlQueryBuilder::exists("city", "country", ["city_name" => "nguyen"])->executeQuery(); print_r($result);