Форум программистов, компьютерный форум, киберфорум
PHP: Symfony
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 06.07.2019
Сообщений: 3
1

Возможно ли используя Criteria выбрать данные из связанных таблиц одним запросом?

31.01.2020, 11:16. Показов 1989. Ответов 2

Author24 — интернет-сервис помощи студентам
Здравстуйте!

Проект использует Symfony 3, Doctrine 2.

Есть таблица объявлений и таблица пользователей, которые эти объявления подали.
При выводе списка объявлений надо показывать имена пользователей.

То есть хочется чтобы выполнился запрос вида
T-SQL
1
2
3
SELECT adverts.title, adverts.body, users.name 
FROM adverts 
LEFT JOIN users ON users.id = adverts.user_id
Не могу понять, возможно ли сделать это с помощью аннотаций OneToMany и ManyToOne используя Criteria

У меня сейчас так:

Фрагмент сушности Adverts
PHP
1
2
3
4
5
6
    /**
     * @var Users
     * @ORM\ManyToOne(targetEntity="Users", inversedBy="advertsByUserId")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
    */
    private $userObject;
Фрагмент сушности Users
PHP
1
2
3
4
5
   /**
     * @var array of Adverts
     * @ORM\OneToMany(targetEntity="Adverts", mappedBy="userObject")
    */
    protected $advertsByUserId;
Фрагмент контроллера

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * 
 * @param string $sRegion = '' код региона латинскими буквами
 * @param string $sCity = ''   код города латинскими буквами
 * @return array
*/
private function _loadAdvList(string $sRegion = '', string $sCity = '', Request $oRequest) : array 
{
    $limit = $this->getParameter('app.records_per_page', 10);
    $repository = $this->getDoctrine()->getRepository('App:Adverts');
    
    $oCriteria = Criteria::create();
    $e = Criteria::expr();
    $oCriteria->where( $e->eq('isDeleted', 0) )
        ->andWhere( $e->eq('isHide', 0) )
        ->andWhere( $e->eq('isModerate', 1) )
        ->orderBy(['delta' => Criteria::DESC])
        ->setMaxResults($limit)
        ->setFirstResult(0);
    
 
    //тут ещё разные фильтры по полям Adverts устанавливаются, думаю в контексте вопроса не принципиально, вырезал
    
    
    $aCollection = $repository->matching($oCriteria)->toArray();
    return $aCollection;
}

Фрагмент view
HTML5
1
2
3
4
5
6
7
    <div class="name">
        {% if (item.userObject) %}
            {{ item.userObject.displayName }}
        {% else %}
            {{ item.id }}
        {% endif %}
    </div>

В итоге имеем
1 Запрос в таблицу adverts и
10 SQL запросов в таблицу users, по одному на каждое объявление

Я понимаю, как это можно сделать одним запросом используя queryBuilder, но возможно ли добиться выборки одним запросом используя Criteria?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.01.2020, 11:16
Ответы с готовыми решениями:

Удаление связанных между собой строк из двух таблиц одним запросом
Здравствуйте. На данный момент имею вот такой код: if ((isset($_SESSION) and...

Sqlite3 Данные из 3 таблиц одним запросом
Добрый день. Нужна помощь гуру sql запросов. Работаю с sqlite3. Пытаюсь вытащить данные из 3...

Выбрать данные одним запросом
create table PrivateMessage ( Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, SenderAccountId INT...

Как одним запросом получить данные из разных таблиц?
Есть таблица со статьями, к статье могут быть прикреплены теги и файлы. есть отдельные таблицы...

2
183 / 110 / 44
Регистрация: 03.07.2016
Сообщений: 496
31.01.2020, 19:34 2
Можно всё)))
И критерия вам не нужна.
$this->getDoctrine()->getRepository('App:Adverts')->createQueryBuilder('a')
->select('a', 'user')
->leftJoin('a.user', 'user')
->where('a.isDeleted = 0')
->andWhere('a.isHide = 0')
->andWhere('a.isModerate = 1')
->order('a.delta', 'DESC')
->setMaxResults($limit)
->setFirstResult(0)
->getQuery()->execute();
Могут быть ошибки я синтаксис не проверял. Суть этого в том что в select вы указываете которые сущности нужно выгрузить сразу. В этом случае я как бы указываю что дай мне все обьявления и сразу выгрузи юзеров.

Добавлено через 3 минуты
Цитата Сообщение от byte256 Посмотреть сообщение
но возможно ли добиться выборки одним запросом используя Criteria?
От блин, поздно увидел))) Можно попробовать связь fetch="eager" навесить но тогда юзер будет постоянно подгружаться с обьявлениями. Ну и если в критериях есть select(не на чем проверить щас) то может и получиться
0
0 / 0 / 0
Регистрация: 06.07.2019
Сообщений: 3
01.02.2020, 09:41  [ТС] 3
Большое спасибо за ответ!

Цитата Сообщение от Borsche Посмотреть сообщение
fetch="eager"
О таком не знал, буду разбираться.

Хочу остановиться на том, почему я не хочу использовать QueryBuilder (или использовать его как можно реже), возможно что-то ещё подскажете.

Насколько я понимаю (тестировал уже довольно давно, месяц-два назад), если в проекте настроен second_level_cache и в моделях указан @ORM\Cache

то получение данных методом

PHP
1
$aCollection = $repository->matching($oCriteria)->toArray()
ищет результат в memcache по умолчанию. Мне это кажется правильным, поэтому я стараюсь использовать Criteria.

А в случае с QueryBuilder мы каждый раз в коде должны явно вызывать метод
PHP
1
enableResultCache($ttl)
для использования result_cache, ( или
PHP
1
setCacheble(true)
если хотим использовать second_level_cache) что не удобно и чревато тем, что иногда можно просто забыть вызвать метод, указывающий получать результат из кэша.
0
01.02.2020, 09:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.02.2020, 09:41
Помогаю со студенческими работами здесь

Получение одним запросом данные из двух разных таблиц PDO
Как объединить два запроса, чтобы выводились все записи из table1 с возможность получить данные еще...

Выбрать данные из связанных таблиц
Доброго времени суток, уважаемы форумчане. Имеются у меня две таблицы: MedLook (мед.осмотр...

Выбрать данные, посчитать строки и сделать update одним запросом
Здравствуйте, есть таблица films(родительская) CREATE TABLE `films` ( `film_id` bigint(20) NOT...

Как одним запросом собрать данные из разных таблиц на примере базы данных?
не могу сдвинуться с мертвой точки: есть заполненные таблицы: &quot;приход&quot;, &quot;расход&quot;, &quot;отчисления&quot;....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru