-
Notifications
You must be signed in to change notification settings - Fork 1
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();
待补充