В одноименном взаимодействии M: M, как получить привязанные к объектам без извлечения владельца? [Дубликат]

Если вы не кодируете веб-приложение, убедитесь, что ваш класс, в котором выполняется @Autowiring, является весенним бобом. Как правило, весенний контейнер не будет знать о классе, который мы могли бы назвать весенним бобом. Мы должны рассказать весенний контейнер о наших весенних классах.

Этого можно достичь путем настройки в appln-contxt или лучший способ - аннотировать класс как @Component и, пожалуйста, не создавайте аннотированный класс, используя новый оператор. Убедитесь, что вы получили его из контекста Appln, как показано ниже.

@Component
public class MyDemo {


    @Autowired
    private MyService  myService; 

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            System.out.println("test");
            ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
            System.out.println("ctx>>"+ctx);

            Customer c1=null;
            MyDemo myDemo=ctx.getBean(MyDemo.class);
            System.out.println(myDemo);
            myDemo.callService(ctx);


    }

    public void callService(ApplicationContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("---callService---");
        System.out.println(myService);
        myService.callMydao();

    }

}
18
задан Gnuffo1 25 March 2011 в 13:28
поделиться

5 ответов

Я не мог понять, как заставить работать с родными запросами, поэтому решил немного взлохмоло:

$id = $em->getConnection()->fetchColumn("SELECT
    pages.id
    FROM
    pages
    INNER JOIN siteversion_page ON siteversion_page.page_id = pages.id
    INNER JOIN siteversions ON siteversion_page.siteversion_id = siteversions.id
    WHERE siteversions.id = 1
    AND pages.slug = 'index'");

$page = $em->find('Page', $id);

Мне это не нравится, потому что это приводит к большему количеству запросов к базе данных (особенно если мне нужно получить массив страниц вместо одного), но он работает.

Edit: Я решил просто пойти с классом для ассоциации. Теперь я могу выполнить этот запрос:

SELECT p FROM Page p, SiteVersionPageLink l
WHERE l.page = p AND l.siteVersion = 5 AND p.slug = 'index'
1
ответ дан Gnuffo1 22 August 2018 в 22:02
поделиться
  • 1
    Вам не нужна ассоциация, если этот вид пересечения редок. Да, это упрощает вещи, но вы получаете некоторые недостатки в производительности при увлажнении объектов. – Ocramius 16 March 2013 в 04:02

Я нашел возможное решение этой проблемы здесь .

В соответствии с этой страницей ваш запрос должен выглядеть примерно так:

SELECT p FROM SiteVersion v, Page p WHERE v.id = 5 AND p.slug='index' AND v.page = p;

Решает ли ваша проблема?

0
ответ дан Imi Borbas 22 August 2018 в 22:02
поделиться
  • 1
    Нет. Проблема в том, что это много-ко-многим, а не один-ко-многим. Это v.pages, а не v.page, но даже если я это делаю: & quot; SELECT p FROM SiteVersion v, Page p WHERE v.id = 5 И p.slug = 'index' AND v.pages = p & quot; (Error: Invalid PathExpression). StateFieldPathExpression или SingleValuedAssociationField ожидается.) – Gnuffo1 25 March 2011 в 14:04
  • 2
    Тогда почему бы вам не указать другую сторону отношений в определении схемы? – Imi Borbas 25 March 2011 в 14:07
  • 3
    Потому что я хочу просто оставить этот модуль, не затрагивая ничего, что уже есть. – Gnuffo1 25 March 2011 в 14:10
  • 4
    Является ли использование родного sql для выбора, по крайней мере, id id страницы является жизнеспособным вариантом для вас? Конечно, было бы гораздо проще использовать DQL ... – Imi Borbas 25 March 2011 в 14:13

Попробуйте это (или что-то в этом роде):

SELECT p FROM Page p WHERE EXISTS (SELECT v FROM SiteVersion v WHERE p MEMBER OF v.pages AND v.id = 5 AND p.slug = 'index')

Я не тестировал это точно, но у меня что-то похожее на работу. Использование EXISTS и MEMBER OF зарывается в разделе DQL Select Examples главы DQL.

1
ответ дан Jon L. 22 August 2018 в 22:02
поделиться

В Doctrine ORM есть два способа справиться с этим. Наиболее типичным является использование условия IN с подзапросом:

SELECT
    p
FROM
    SitePage p
WHERE
    p.id IN(
        SELECT
            p2.id
        FROM
            SiteVersion v
        JOIN
            v.pages p2
        WHERE
            v.id = :versionId
            AND
            p.slug = :slug
    )

. Другой способ заключается в дополнительном соединении с функцией произвольного соединения, введенной в версии 2.3 ORM :

SELECT
    p
FROM
    SitePage p
JOIN
    SiteVersion v
WITH
    1 = 1
JOIN
    v.pages p2
WHERE
    p.id = p2.id
    AND
    v.id = :versionId
    AND
    p2.slug = :slug

1 = 1 происходит только из-за ограничения тока синтаксического анализатора.

Обратите внимание, что ограничение, которое вызывает семантическую ошибку заключается в том, что процесс гидратации начинается с корня выбранных объектов. Без корень на месте гидратор не имеет никакого отношения к тому, как свернуть с помощью fetch-join или объединить результаты.

24
ответ дан Ocramius 22 August 2018 в 22:02
поделиться
  • 1
    Является ли это еще лучшей практикой для этого сценария или есть что-то для этого сейчас в доктрине 2.5? – Steffen Brem 16 March 2016 в 00:38
  • 2
    Да, это не изменилось. – Ocramius 16 March 2016 в 13:13
  • 3
    Также я хотел бы знать, влияет ли это на производительность (1 = 1 часть)? В противном случае мне пришлось бы искать другое решение для этого, у меня есть много DQL-запросов, которые должны присоединиться к этому. – Steffen Brem 3 November 2016 в 14:05
  • 4
    Нет, приличные планировщики SQL отделяют сравнение до выполнения запроса. – Ocramius 7 November 2016 в 10:48

Я думаю, вам нужно также выбрать SiteVersion в вашем запросе:

SELECT v, p FROM SiteVersion v JOIN v.pages p WHERE v.id = 5 AND p.slug='index'

Вы получите массив объектов SiteVersion, которые вы можете пропустить, чтобы получить сущности страницы.

2
ответ дан rojoca 22 August 2018 в 22:02
поделиться
  • 1
    Это приведет к присоединению страниц сайта к версиям сайта, возвращению списка объектов SiteVersion, а не только страниц сайта. Это действительно неверно, учитывая ожидаемые результаты (на вопрос). – Ocramius 16 March 2013 в 03:56
Другие вопросы по тегам:

Похожие вопросы: