Как выполнить поиск с использованием спецификаций jpa в соединении 2 таблиц?

#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?