Skip to content

Hyperf查询构造器 beta

free2one edited this page Oct 20, 2023 · 4 revisions

除Doctrine原生提供的QueryBuilder外,我们也同步适配了Hyperf框架的查询构造器。

与原有Hyperf框架的查询构造器不同,适配Doctrine的构造器将生成DQL语句,而不是SQL。为了满足DQL的语法,相较原有构造器,其在调用上将存在细微变化,功能上也会有部分限制。

查询

我们仍以入门章节中的User实体类做为例子,用原生Hyperf查询构造器时,若需查询名称为小明的用户时,代码应如下所示:

$builder = \Hyperf\DbConnection\Db::table('user');  
$builder  
    ->where('name', '=', '小明')  
    ->get();

适配后的Hyperf查询构造器,调用方式将变更如下:

$em = EntityManagerFactory::getManager();  
$builder = $em->createHyperfQueryBuilder();  
$builder  
    ->select('user')  
    ->from(User::class, 'user')  
    ->where('user.userName', '=', '小明')  
    ->get();

首先,别名是必须的。以上述例子中,我们在from方法中设置了实体类及别名,并在select中填写该别名(最终将转化为对应的实体对象)。 其次,条件语句中我们不再允许编写任何数据库列名,而是以别名+实体属性的方式进行设置。 我们不妨看看解析前后的DQL及SQL语句:

SELECT user FROM App\Domain\Entity\User user WHERE user.userName = ?0

DQL

SELECT u0_.id AS id_0, u0_.name AS name_1, u0_.gender AS gender_2, u0_.version AS version_3 FROM user u0_ WHERE u0_.name = ?

SQL

select参数的影响

上述查询语句将返回包含User实体类的集合

object(Hyperf\Collection\Collection)#573 (1) {
  ["items":protected]=>
  array(2) {
    [0]=>
    object(App\Domain\Entity\User)#586 (4) {
      ["id":protected]=>
      int(1)
      ["userName":protected]=>
      string(5) "小明"
    }
  }
}

与此同时,构造器也允许指定属性进行查询,但相关属性将会被认为是标量(Scalar),从而影响返回的数据结构。我们不妨看看下述例子:

$res = $builder
	->select('user.userName', 'user.id')
	->from(User::class, 'user')
	->where('user.userName', '=', '小明')
	->get();

响应体如下

^ Hyperf\Utils\Collection^ {#893
  #items: array:1 [
    0 => array:2 [
      "userName" => "小明"
      "id" => 1
    ]
  ]
}

另外,我们也支持混合模式。若我们把select的传参更改为select('user','user.userName'),返回结果将变更如下。

^ Hyperf\Utils\Collection^ {#894
  #items: array:1 [
    0 => array:2 [
      0 => App\Domain\Entity\User^ {#860
        -id: 1
        -userName: "小明"
        }
      }
      "userName" => "小明"
    ]
  ]
}

持久化

插入

Doctrine的DQL并不支持INSERT类型的执行语句,因此调用查询构造器的insert方法将产生报错。

$builder
	->from(User::class, 'user')  
	->insert(['user.userName' => 'name100', 'user.gender' => 1]);

以上语句将抛出异常RuntimeException : INSERT statements are not allowed in DQL.Use EntityManager#persist() instead.

更新

$builder
	->from(User::class, 'user')
	->where('user.id', 4)
	->update(['user.userName' => '张三2']);

删除

$builder
	->from(User::class, 'user')
	->where('user.id', 4)
	->delete();

已知限制

待补充

Clone this wiki locally