romainbessugesmeusy/php-sql-query

php-sql-query 是 SQL 查询构建的抽象层

v0.3 2013-12-13 14:52 UTC

This package is not auto-updated.

Last update: 2024-09-14 13:33:37 UTC


README

php-sql-query 包旨在为 SQL 查询构建提供一致的抽象层。它分为两部分

  1. 抽象查询组件(列、表、限制、分组)
  2. 渲染器(MySQL、PgSql、Sql Server)

创建一个选择查询非常简单

$select = new \RBM\SqlQuery\Select();
$select->setTable("project");
$select->setColumns(["project_id", "name"]);
$select->limit(0, 10);

为了根据使用的数据库系统输出正确的查询,您需要实例化渲染器,并调用其渲染方法

$renderer = new \RBM\SqlQuery\RendererAdapter\MySql();
echo $renderer->render($select);

这将打印以下字符串

SELECT
	`project`.`project_id`
	, `project`.`name`
FROM
	`project`
LIMIT 0, 10

希望您不需要这么详细就能完成任务。

// do this once
\RBM\SqlQuery\Select::setDefaultRenderer("\RBM\SqlQuery\RendererAdapter");
// […]
$select = new \RBM\SqlQuery\Select("project", ["project_id", "name"]);
echo $select;

过滤

在这个 API 中没有 ->where() 方法,而是有 ->filter(),它返回一个 \RBM\SqlQuery\Filter 对象。此对象提供了一些基本方法

  • equals($column, $value)
  • greaterThan($column, $value)
  • lowerThanEquals($column, $value)
  • isNull($column)

还有一些更基础的方法,例如

  • in($column, $values)
  • between($column, $a, $b)

所有这些方法都可以链式调用,以提高可读性和易于开发。

	$select = new Select('project', ['project_id', 'name']);
	$select->filter()
		   		->equals('owner_id', 1)
		   		->isNull('date_deleted');

当然,您可以确定所需的运算符,并嵌套子句

	$select->filter()->subFilter()
					->operator('OR')
					->equals('status', 'DRAFT')
					->equals('status', 'PUBLISHED');

结果

	SELECT
		project.project_id
		, project.name
	FROM
		project	
	WHERE
		( project.owner_id = 1 )
	 AND ( project.date_deleted IS NULL )
	 AND (
	 		( project.status = 'DRAFT' )
	 		OR ( project.status = 'PUBLISHED' )
	 	)

SELECT & JOINs

A JOIN 是一个 SELECT。事实上,没有 \RBM\SqlQuery\Join 类,也不会有。

$select = new Select('project', ['project_id', 'name']);
$owner = $select->join('user', 'owner_id', 'user_id');
print_r($owner);

这给了我们

RBM\SqlQuery\Select Object
(
	[_table:protected] => RBM\SqlQuery\Table Object
    	(
        	[_name:protected] => user
…

将 JOIN 视为 SELECT 的最大优势是可重用性。假设您有一个提供一些选择查询的实体。

class UserEntity 
{

	public function getSelectForActiveUsers()
	{
		$select = new Select('user');
		$select->filter()->equals('active', 1);
		return $select;
	}
	
}	

class ProjectEntity 
{

	public function getSelectForProjectsOfActiveUsers()
	{
		$userEntity = new UserEntity();
		$select = new Select('project');
		$select->addJoin($userEntity->getSelectForActiveUsers(), 'owner_id', 'user_id');
	}	
}

重载和继承

这个包的一个有趣特性是它可以扩展以自定义查询和过滤层。继承的最终目的是使查询构建对象化,使其更加流畅且面向业务。

###选择

在扩展选择时,您会发现最明显的用法是为连接定义快捷方式

class ProjectSelect extends \RBM\SqlQuery\Select
{
	// overloading the table (simple way)
	protected $_table = 'project';

	public function owner()
	{
		return $this->join('user', 'owner_id', 'user_id');
	}
}

用法

$projects = new ProjectSelect();
$projects->owner()->filter()->equals('user_id', 1);

###过滤

为我们的项目表创建一个过滤器很简单

class ProjectFilter extends \RBM\SqlQuery\Filter
{
	public function deleted($deleted)
	{
		return ($deleted) ? $this->isNull('date_deleted') : $this->isNotNull('date_deleted');
	}
}

要使用此过滤器,您需要修改选择中的 filterClass 属性

$projects = new ProjectSelect();
$projects->filter()->deleted(true);