cakephp 3 order by query 生成 14 个带有关联表的查询而不是 1 个
cakephp 3 order by query generates 14 queries with associate tables instead of 1
我的 cakephp3 应用程序运行良好,现在我希望通过关联的 table 字段对一些查询进行排序。
当按当前模型中的字段排序时,查询工作正常。但是,如果我选择按关联 table 中的字段 Models.field
进行排序,我现在会得到 14 sql 个查询,而不是一个。但真正的问题是 ORDER BY
不包含在查询中。
我在具有 employee_id 和 course_id 字段的 CoursesEmployees 模型中。
CoursesEmployeesController.php
public function certificate() {
$this->paginate = [
'sortWhitelist' => [
'Employees.surname', 'Courses.name', 'date_completed'
],
'conditions' => ['CoursesEmployees.completed' => true, 'Employees.user_id' => $this->Auth->user('id')],
'contain' => ['Employees', 'Courses'],
'order' => ['Employees.name'=>'asc']
];
$this->set('coursesEmployees', $this->paginate($this->CoursesEmployees));
}
如果我通过 'order' => ['date_created'=>'asc']
订购,我会收到一个查询并且一切正常。
SELECT
CoursesEmployees.id AS `CoursesEmployees__id`,
CoursesEmployees.employee_id AS `CoursesEmployees__employee_id`,
CoursesEmployees.course_id AS `CoursesEmployees__course_id`,
CoursesEmployees.course_module_id AS `CoursesEmployees__course_module_id`,
CoursesEmployees.cid AS `CoursesEmployees__cid`,
CoursesEmployees.progress AS `CoursesEmployees__progress`,
CoursesEmployees.modified AS `CoursesEmployees__modified`,
CoursesEmployees.created AS `CoursesEmployees__created`,
CoursesEmployees.completed AS `CoursesEmployees__completed`,
CoursesEmployees.date_completed AS `CoursesEmployees__date_completed`,
Employees.id AS `Employees__id`,
Employees.user_id AS `Employees__user_id`,
Employees.hotel_id AS `Employees__hotel_id`,
Employees.name AS `Employees__name`,
Employees.email AS `Employees__email`,
Employees.surname AS `Employees__surname`,
Employees.employee_num AS `Employees__employee_num`,
Employees.modified AS `Employees__modified`,
Employees.created AS `Employees__created`,
Courses.id AS `Courses__id`,
Courses.name AS `Courses__name`,
Courses.course_lenght AS `Courses__course_lenght`
FROM
courses_employees CoursesEmployees
INNER JOIN
employees Employees
ON Employees.id = (
CoursesEmployees.employee_id
)
INNER JOIN
courses Courses
ON Courses.id = (
CoursesEmployees.course_id
)
WHERE
(
CoursesEmployees.completed = 1
AND Employees.user_id = '1'
)
ORDER BY
CoursesEmployees.date_completed asc LIMIT 20 OFFSET 0
如果我 'order' => ['Employees.name'=>'asc']
(或字段名称的任何随机文本)我得到 14 sql 个查询,而主查询没有按应有的顺序排列。
SHOW FULL COLUMNS FROM `courses_employees` 10 1
SHOW INDEXES FROM `courses_employees` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'courses_employees' and rc.TABLE_NAME = 'courses_employees' 0 0
SHOW TABLE STATUS WHERE Name = 'courses_employees' 1 0
SHOW FULL COLUMNS FROM `employees` 9 1
SHOW INDEXES FROM `employees` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'employees' and rc.TABLE_NAME = 'employees' 0 0
SHOW TABLE STATUS WHERE Name = 'employees' 1 0
SHOW FULL COLUMNS FROM `courses` 3 1
SHOW INDEXES FROM `courses` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'courses' and rc.TABLE_NAME = 'courses' 0 0
SHOW TABLE STATUS WHERE Name = 'courses' 1 0
SELECT
CoursesEmployees.id AS `CoursesEmployees__id`,
CoursesEmployees.employee_id AS `CoursesEmployees__employee_id`,
CoursesEmployees.course_id AS `CoursesEmployees__course_id`,
CoursesEmployees.course_module_id AS `CoursesEmployees__course_module_id`,
CoursesEmployees.cid AS `CoursesEmployees__cid`,
CoursesEmployees.progress AS `CoursesEmployees__progress`,
CoursesEmployees.modified AS `CoursesEmployees__modified`,
CoursesEmployees.created AS `CoursesEmployees__created`,
CoursesEmployees.completed AS `CoursesEmployees__completed`,
CoursesEmployees.date_completed AS `CoursesEmployees__date_completed`,
Employees.id AS `Employees__id`,
Employees.user_id AS `Employees__user_id`,
Employees.hotel_id AS `Employees__hotel_id`,
Employees.name AS `Employees__name`,
Employees.email AS `Employees__email`,
Employees.surname AS `Employees__surname`,
Employees.employee_num AS `Employees__employee_num`,
Employees.modified AS `Employees__modified`,
Employees.created AS `Employees__created`,
Courses.id AS `Courses__id`,
Courses.name AS `Courses__name`,
Courses.course_lenght AS `Courses__course_lenght`
FROM
courses_employees CoursesEmployees
INNER JOIN
employees Employees
ON Employees.id = (
CoursesEmployees.employee_id
)
INNER JOIN
courses Courses
ON Courses.id = (
CoursesEmployees.course_id
)
WHERE
(
CoursesEmployees.completed = 1
AND Employees.user_id = '1'
) LIMIT 20 OFFSET 0
如果您立即重新运行 脚本,您应该会看到那些查询消失了。
这些查询用于获取数据以生成模式和其他元数据,默认情况下,这应该很少发生,因为数据正在被缓存,因为在您的应用程序数据源配置中启用了 cacheMetadata
。
默认情况下,数据缓存 2 分钟,请检查您的应用缓存配置 _cake_model_
。这是当应用程序处于调试模式 运行ning 时将要使用的值。当不处于调试模式时,持续时间默认设置为 1 年,请检查您的应用 boostrap.php
.
另见
- https://github.com/cakephp/app/blob/3.2.6/config/app.default.php#L117
- https://github.com/cakephp/app/blob/3.2.6/config/bootstrap.php#L87-L93
- Cookbook > Database Access & ORM > Database Basics > Metadata Caching
- Cookbook > Database Access & ORM > ORM Cache Shell
至于您缺少订单字段的问题,您在白名单中缺少 Employees.name
字段,但是即使将其他型号的字段列入白名单似乎也不起作用。
这似乎是分页器中的一个错误,即在 PaginatorComponent::_prefix()
方法中,该字段被吞没,最终导致一个空的 order
选项被传递给查询。
看起来这已经被报道过,fixed 即将发布的 3.0.7 版本。如果您等不及,请抓住 master 分支或应用补丁。
我的 cakephp3 应用程序运行良好,现在我希望通过关联的 table 字段对一些查询进行排序。
当按当前模型中的字段排序时,查询工作正常。但是,如果我选择按关联 table 中的字段 Models.field
进行排序,我现在会得到 14 sql 个查询,而不是一个。但真正的问题是 ORDER BY
不包含在查询中。
我在具有 employee_id 和 course_id 字段的 CoursesEmployees 模型中。
CoursesEmployeesController.php
public function certificate() {
$this->paginate = [
'sortWhitelist' => [
'Employees.surname', 'Courses.name', 'date_completed'
],
'conditions' => ['CoursesEmployees.completed' => true, 'Employees.user_id' => $this->Auth->user('id')],
'contain' => ['Employees', 'Courses'],
'order' => ['Employees.name'=>'asc']
];
$this->set('coursesEmployees', $this->paginate($this->CoursesEmployees));
}
如果我通过 'order' => ['date_created'=>'asc']
订购,我会收到一个查询并且一切正常。
SELECT
CoursesEmployees.id AS `CoursesEmployees__id`,
CoursesEmployees.employee_id AS `CoursesEmployees__employee_id`,
CoursesEmployees.course_id AS `CoursesEmployees__course_id`,
CoursesEmployees.course_module_id AS `CoursesEmployees__course_module_id`,
CoursesEmployees.cid AS `CoursesEmployees__cid`,
CoursesEmployees.progress AS `CoursesEmployees__progress`,
CoursesEmployees.modified AS `CoursesEmployees__modified`,
CoursesEmployees.created AS `CoursesEmployees__created`,
CoursesEmployees.completed AS `CoursesEmployees__completed`,
CoursesEmployees.date_completed AS `CoursesEmployees__date_completed`,
Employees.id AS `Employees__id`,
Employees.user_id AS `Employees__user_id`,
Employees.hotel_id AS `Employees__hotel_id`,
Employees.name AS `Employees__name`,
Employees.email AS `Employees__email`,
Employees.surname AS `Employees__surname`,
Employees.employee_num AS `Employees__employee_num`,
Employees.modified AS `Employees__modified`,
Employees.created AS `Employees__created`,
Courses.id AS `Courses__id`,
Courses.name AS `Courses__name`,
Courses.course_lenght AS `Courses__course_lenght`
FROM
courses_employees CoursesEmployees
INNER JOIN
employees Employees
ON Employees.id = (
CoursesEmployees.employee_id
)
INNER JOIN
courses Courses
ON Courses.id = (
CoursesEmployees.course_id
)
WHERE
(
CoursesEmployees.completed = 1
AND Employees.user_id = '1'
)
ORDER BY
CoursesEmployees.date_completed asc LIMIT 20 OFFSET 0
如果我 'order' => ['Employees.name'=>'asc']
(或字段名称的任何随机文本)我得到 14 sql 个查询,而主查询没有按应有的顺序排列。
SHOW FULL COLUMNS FROM `courses_employees` 10 1
SHOW INDEXES FROM `courses_employees` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'courses_employees' and rc.TABLE_NAME = 'courses_employees' 0 0
SHOW TABLE STATUS WHERE Name = 'courses_employees' 1 0
SHOW FULL COLUMNS FROM `employees` 9 1
SHOW INDEXES FROM `employees` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'employees' and rc.TABLE_NAME = 'employees' 0 0
SHOW TABLE STATUS WHERE Name = 'employees' 1 0
SHOW FULL COLUMNS FROM `courses` 3 1
SHOW INDEXES FROM `courses` 1 0
SELECT * FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON (kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME) WHERE kcu.TABLE_SCHEMA = 'deep_mind' AND kcu.TABLE_NAME = 'courses' and rc.TABLE_NAME = 'courses' 0 0
SHOW TABLE STATUS WHERE Name = 'courses' 1 0
SELECT
CoursesEmployees.id AS `CoursesEmployees__id`,
CoursesEmployees.employee_id AS `CoursesEmployees__employee_id`,
CoursesEmployees.course_id AS `CoursesEmployees__course_id`,
CoursesEmployees.course_module_id AS `CoursesEmployees__course_module_id`,
CoursesEmployees.cid AS `CoursesEmployees__cid`,
CoursesEmployees.progress AS `CoursesEmployees__progress`,
CoursesEmployees.modified AS `CoursesEmployees__modified`,
CoursesEmployees.created AS `CoursesEmployees__created`,
CoursesEmployees.completed AS `CoursesEmployees__completed`,
CoursesEmployees.date_completed AS `CoursesEmployees__date_completed`,
Employees.id AS `Employees__id`,
Employees.user_id AS `Employees__user_id`,
Employees.hotel_id AS `Employees__hotel_id`,
Employees.name AS `Employees__name`,
Employees.email AS `Employees__email`,
Employees.surname AS `Employees__surname`,
Employees.employee_num AS `Employees__employee_num`,
Employees.modified AS `Employees__modified`,
Employees.created AS `Employees__created`,
Courses.id AS `Courses__id`,
Courses.name AS `Courses__name`,
Courses.course_lenght AS `Courses__course_lenght`
FROM
courses_employees CoursesEmployees
INNER JOIN
employees Employees
ON Employees.id = (
CoursesEmployees.employee_id
)
INNER JOIN
courses Courses
ON Courses.id = (
CoursesEmployees.course_id
)
WHERE
(
CoursesEmployees.completed = 1
AND Employees.user_id = '1'
) LIMIT 20 OFFSET 0
如果您立即重新运行 脚本,您应该会看到那些查询消失了。
这些查询用于获取数据以生成模式和其他元数据,默认情况下,这应该很少发生,因为数据正在被缓存,因为在您的应用程序数据源配置中启用了 cacheMetadata
。
默认情况下,数据缓存 2 分钟,请检查您的应用缓存配置 _cake_model_
。这是当应用程序处于调试模式 运行ning 时将要使用的值。当不处于调试模式时,持续时间默认设置为 1 年,请检查您的应用 boostrap.php
.
另见
- https://github.com/cakephp/app/blob/3.2.6/config/app.default.php#L117
- https://github.com/cakephp/app/blob/3.2.6/config/bootstrap.php#L87-L93
- Cookbook > Database Access & ORM > Database Basics > Metadata Caching
- Cookbook > Database Access & ORM > ORM Cache Shell
至于您缺少订单字段的问题,您在白名单中缺少 Employees.name
字段,但是即使将其他型号的字段列入白名单似乎也不起作用。
这似乎是分页器中的一个错误,即在 PaginatorComponent::_prefix()
方法中,该字段被吞没,最终导致一个空的 order
选项被传递给查询。
看起来这已经被报道过,fixed 即将发布的 3.0.7 版本。如果您等不及,请抓住 master 分支或应用补丁。