Spring data , как написать запрос?

192
23 ноября 2017, 03:21

Есть сущности :

Train:

package dev5.lavishek.trains.entity;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
@Table
@Entity
public class Train extends BaseEntity {
  @ManyToMany(fetch = FetchType.EAGER)
  private List<DayOfWeek> availableDay = new ArrayList<>();
  @OneToMany
  @LazyCollection(LazyCollectionOption.FALSE)
  private List<Ride> rides = new ArrayList<>();
  @ManyToMany
  private List<RailwayCarriage> carriages = new ArrayList<>();
  public Train() {
  }
  public Train(List<DayOfWeek> availableDay, List<Ride> rides,
      List<RailwayCarriage> carriages) {
    this.availableDay = availableDay;
    this.rides = rides;
    this.carriages = carriages;
  }

  public List<DayOfWeek> getAvailableDay() {
    return availableDay;
  }
  public void setAvailableDay(List<DayOfWeek> availableDay) {
    this.availableDay = availableDay;
  }
  public List<RailwayCarriage> getCarriages() {
    return carriages;
  }
  public void setCarriages(List<RailwayCarriage> carriages) {
    this.carriages = carriages;
  }
  public List<Ride> getRides() {
    return rides;
  }
  public void setRides(List<Ride> rides) {
    this.rides = rides;
  }
  @Override
  public String toString() {
    return super.toString() + "availableDay=" + availableDay +
        " rides=" + rides +
        ", carriages=" + carriages;
  }
}

DayOfWeek :

package dev5.lavishek.trains.entity;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table
public class DayOfWeek extends BaseEntity {
  @Column
  private java.time.DayOfWeek dayOfWeek;
  @ManyToMany(mappedBy = "availableDay")
  private List<Train> trains = new ArrayList<>();
  public DayOfWeek() {
  }
  public DayOfWeek(java.time.DayOfWeek dayOfWeek) {
    this.dayOfWeek = dayOfWeek;
  }
  public java.time.DayOfWeek getDayOfWeek() {
    return dayOfWeek;
  }
  public void setDayOfWeek(java.time.DayOfWeek dayOfWeek) {
    this.dayOfWeek = dayOfWeek;
  }
  public List<Train> getTrains() {
    return trains;
  }
  public void setTrains(List<Train> trains) {
    this.trains = trains;
  }
  @Override
  public String toString() {
    return
        super.toString() + "dayOfWeek=" + dayOfWeek;
  }
}

Ride:

package dev5.lavishek.trains.entity;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table
public class Ride extends BaseEntity {
  @ManyToOne(fetch = FetchType.EAGER)
  private Schedule schedule;
  @ManyToOne(fetch = FetchType.EAGER)
  private Station stationFrom;
  @ManyToOne(fetch = FetchType.EAGER)
  private Station stationTo;
  public Ride(Schedule schedule, Station stationFrom, Station stationTo) {
    this.schedule = schedule;
    this.stationFrom = stationFrom;
    this.stationTo = stationTo;
  }
  public Ride() {
  }
  public Ride(Integer id, Schedule schedule, Station stationFrom,
      Station stationTo) {
    super(id);
    this.schedule = schedule;
    this.stationFrom = stationFrom;
    this.stationTo = stationTo;
  }
  public Ride(Integer id) {
    super(id);
  }
  public Schedule getSchedule() {
    return schedule;
  }
  public void setSchedule(Schedule schedule) {
    this.schedule = schedule;
  }
  public Station getStationFrom() {
    return stationFrom;
  }
  public void setStationFrom(Station stationFrom) {
    this.stationFrom = stationFrom;
  }
  public Station getStationTo() {
    return stationTo;
  }
  public void setStationTo(Station stationTo) {
    this.stationTo = stationTo;
  }
  @Override
  public String toString() {
    return super.toString() + "schedule=" + schedule +
        ", stationFrom=" + stationFrom +
        ", stationTo=" + stationTo;
  }
}

Необходимо написать запрос (@Query) для Train :

  @Query()
  List<Train> getTrainByAvailableDayAndStations(@Param("AvailableDay") DayOfWeek day,
      @Param("FromSt") Station from,
      @Param("ToSt") Station to);

Надо выбрать все поезда у которых есть @Param("AvailableDay") и в списке train.rides есть ride у которого stationFrom совпадает с @Param("FromSt") , и ride у которого stationTo совпадает с @Param("ToSt"), при чем это могут быть разные ride из списка train.rides .

Еще если это реально желательно проверить , что индекс ride который содержит FromSt меньше индекса ride , который содержит ToSt в списке train.ride

В данный момент реализовал так :

@Query(value = "
SELECT train FROM 
Train train INNER JOIN train.rides ride INNER JOIN train.availableDay day 
WHERE (day.dayOfWeek=:AvailableDay) AND
        (ride.stationFrom=:FromSt OR ride.stationTo=:ToSt) 
GROUP BY train.id)
")

Но проблема в том ,что здесь Ride это одна и та же поездка, а нужно у разных , + мне почему то возвращает несколько train с одинаковым id, поэтому использую костыль ( GROUP By ).

Answer 1

Ну если вам нужно разные поездки, так и пишите разные поездки, как-то так (не проверял, но суть должны быть понятна)

@Query(value = "
SELECT train FROM 
Train train INNER JOIN train.rides ride1 INNER JOIN train.rides ride2
    INNER JOIN train.availableDay day 
WHERE (day.dayOfWeek=:AvailableDay) AND
        (ride1.stationFrom=:FromSt OR ride2.stationTo=:ToSt) 
GROUP BY train.id)
")

А то что у вас несколько раз возвращается train это нормально, так как сущностей ride у train много он для каждой вернет train (sql же не в курсе что вам нужны только уникальные id). Можете попробовать так

@Query(value = "
SELECT DISTINCT train FROM 
Train train INNER JOIN train.rides ride1 INNER JOIN train.rides ride2
    INNER JOIN train.availableDay day 
WHERE (day.dayOfWeek=:AvailableDay) AND
        (ride1.stationFrom=:FromSt OR ride2.stationTo=:ToSt) 
)
")

Но я не уверен, поддерживается ли DISTINCT всегда и везде (вроде он в стандарте SQL, но всякое бывает).

READ ALSO
primefaces + MySQL + jsf +Tomcat

primefaces + MySQL + jsf +Tomcat

Задача состоит в том, что нужно создать просто элементарно веб приложение с интегрированной базой данных, используя технологию primefacesВ базе...

187
Синхронизация кнопок с календарем Android приложение

Синхронизация кнопок с календарем Android приложение

Есть ли такая возможность и, если есть, то каким образом можно синхронизировать некоторое количество кнопок с календарем на телефоне?

224
Перенос текста в ячейке TableView

Перенос текста в ячейке TableView

Как сделать чтобы в ячейке таблицы текст переносился на следующую строчку, чтобы высота ячейки увеличивалась

250
Delphi 2D. Статическое изменение рисунка

Delphi 2D. Статическое изменение рисунка

Необходимо сделать мнемосхему на DelphiДелал подобные на Java

201