#mysql #spring-boot #jpa #join #specifications
#mysql #пружинный ботинок #jpa #Присоединиться #технические характеристики
Вопрос:
У меня есть 2 таблицы, а именно таблица 1 и таблица 2. Я хочу иметь спецификацию JPA, которая выполняет поиск по соединению двух таблиц, т. Е. По некоторым полям таблицы 1 и некоторым полям таблицы 2. 2 таблицы выглядят следующим образом:
@Entity @Table(name = "table1") public class Table1 { @Id @Column(name = "SID1", nullable = false) private Long sid1; @Column(name = "field1") private Long field1; @Column(name = "field2") private String field2; @Column(name = "SID2", nullable = false) private Long sid2; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "SID2") private Table2 t2; }
и
@Entity @Table(name = "table2") public class Table2 { @Id @Column(name = "SID2", nullable = false) private Long sid2; @Column(name = "field01") private Long field01; @Column(name = "field02") private String field02; }
Я хочу создать спецификацию и ее спецификациюbuilde, но понятия не имею, как ссылаться на поля таблицы 2 из root.get(). Для бывших
public static Specificationlt;Table1gt; hasField01(final String field) { return (root, query, cb) -gt; cb.equal(root.get("t2.field01"), field); //is this correct?? }
Я изучил идею создания 2 запросов к каждой таблице отдельно, но это становится громоздким. Ваша помощь была бы признательна.
Комментарии:
1. Вы хотите сделать ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ? В противном случае таблицы должны быть связаны внешним ключом, и вам нужно присоединиться к ключу. Например, если Таблица 1-Книжная полка, а Таблица 2-Книга, то либо на Книжной полке должен быть списокlt;Книгаgt;, либо в книге должен быть идентификатор книжной полки в качестве внешнего ключа. Какой из них вы хотели бы реализовать?
2. Можете ли вы опубликовать SQL, который вы пытаетесь сгенерировать, тогда мы могли бы перевести его в JPQL.
3. Привет @roccobaroccoSC Я отредактировал вопрос, чтобы быть более прямым. Дайте мне знать, если потребуется какое-либо объяснение.
4. API критериев похож на JPQL, но каждый». » — это отдельный вызов get. Поэтому вместо root.get(«t2.field01»), предполагая, что root находится в таблице 1, это будет root.get(«t2»).get(«field01»), чтобы указать вам путь для использования в других выражениях, таких как equal.
5. Спасибо, это может сработать. Осуществлю сегодня и дам вам знать.
Ответ №1:
Если ваша цель-выполнить поиск в таблице 2.поле 01 при подключении к таблице 1, вы можете использовать следующий запрос JPQL:
SELECT t1 FROM Table1 t1 LEFT JOIN t1.t2 t2 WHERE t2.field01 = :field
При этом будет выбрана Таблица 1, но только записи, объединенные с таблицей 2, имеют поле 01, равное указанному параметру. «:поле» должно быть предоставлено в качестве аргумента для запроса извне, например:
public class Table1DAO { // ... public Listlt;Table1gt; findByField01(Long field01) { try { Listlt;Table1gt; result = entityManager .createQuery("SELECT t1 FROM Table1 t1 LEFT JOIN t1.t2 t2 WHERE t2.field01 = :field", Table1.class) .setParameter("field", field01) .getResultList(); return result; } catch (NoResultException e) { return null; } catch (Exception e) { throw e; } } }
Вы можете выбрать все поля из обеих таблиц или произвольную комбинацию полей, но ваш запрос не может преобразовать такие результаты в таблицу 1, вам необходимо прочитать их в исходном виде из возвращаемого массива:
Listlt;Maplt;String, Objectgt;gt; results = (Listlt;Maplt;String, Objectgt;gt;) query.getResultList();
Комментарии:
1. по некоторым причинам я просто не могу использовать JPQL, вместо этого я должен использовать спецификацию. это связано с тем, что существует множество полей, и любое их количество может иметь значение или нет. и хотя некоторые из этих значений приведены в таблице 1, а другие в таблице 2, отсюда и вопрос.
2. Под спецификациями вы подразумеваете api критериев JPA?