2017-11-27 4 views
0

Die Umgebung ist Java, Spring-Boot, Hibernat, QueryDSL, MySQL.Abfrage Prädikat in QueryDSL

Ich habe Tabellenstruktur

Folge

+----+-------------+-------- 
| id | address_id | eventno 
+----+-------------+-------- 
| 5 |   27 | F123 
| 6 |   30 | F456 
| 7 |   45 | F789 
+----+-------------+-------- 

@Entity 
public class Episode { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 
@NotEmpty 
private String eventno; 
@ManyToOne(cascade = CascadeType.ALL) 
private Address address; 

Episode_Person

+----+--------------+--------------+------------+-----------+ 
| id | episode_role | primary_flag | episode_id | person_id | 
+----+--------------+--------------+------------+-----------+ 
| 19 | Buyer  |    |   5 |   1 | 
| 20 | Subject  |    |   5 |   2 | 
| 23 | Witness  |    |   6 |   3 | 
| 24 | Child  |    |   6 |   4 | 
| 27 | Buyer  |    |   5 |   3 | 
| 63 | Investor  |    |   5 |   4 | 
| 64 | Subject  |    |   7 |   1 | 
| 65 | Subject  |    |   7 |   3 | 

@Entity 
public class EpisodePerson { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 

@ManyToOne 
@Valid 
private Person person; 

@ManyToOne 
private Episode episode; 

Person

+----+-----------+----------+ 
| id | firstname | surname | 
+----+-----------+----------+ 
| 1 | Clint  | eastwood | 
| 2 | Angelina | joilee | 
| 3 | Brad  | pitt  | 
| 4 | Jennifer | aniston | 

@Entity 
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"nia"})) 
public class Person { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 
private String surname; 
private String firstname; 
private String gender; 

Also jede Episode hat mehrere Personen. Und die Join-Tabelle ist Episode_Person.

Meine UI hat eine Datentabelle mit einem Filter an jeder Säule:

enter image description here

Die Filterung funktioniert bereits auf Event- und Adresse. Und sieht aus wie dieses Prädikat in QueryDSL:

  BooleanBuilder where = new BooleanBuilder(); 
     if (pagination.getFilterBy().getMapOfFilters().get("eventno")!=null) { 
      where.and(qEpisode.eventno.containsIgnoreCase(pagination.getFilterBy().getMapOfFilters().get("eventno"))); 
     } 
     if (pagination.getFilterBy().getMapOfFilters().get("address")!=null) { 
      where.and(qEpisode.address.formattedAddress.containsIgnoreCase(pagination.getFilterBy().getMapOfFilters().get("address"))); 
     } 
     where.and(qEpisode.creatingUser.eq(user)); 
     List<Episode> e = episodeRepository.findAll(where); 

Wie würde ich jetzt ein drittes Prädikat für Fall Namen in dem Fall Name der ersten beiden Menschen in der Sammlung von Menschen gegen eine Episode zurück aufgebaut ist?

UPDATE

Zur Klarstellung sichert die DTO das ist die UI-Ansicht, welche die "casename" -Attribut enthält. Es wird in der Dienstschicht erzeugt, wenn Domain-Objekte DTO umgewandelt werden:

episodeDashboard.setNames(episodePersonList.get(0).getPerson().getSurname().toUpperCase() +" & " +episodePersonList.get(1).getPerson().getSurname().toUpperCase()); 
+0

Welche Datenbank verwenden Sie? –

+0

@AlanHay Ich benutze MySQL. –

Antwort

1

nicht leicht, wenn Sie einen Teil der Verarbeitung in die Datenbank übertragen.

Wenn die case_name -Eigenschaft in der Datenbankschicht und nicht als abgeleitete Eigenschaft in der Anwendungslogik aufgefüllt werden kann, wird der Front-End-Code trivial.

Wir können dies mit Hilfe einer Ansicht tun. Die genaue Definition dieser auf Ihrer Datenbank hängt jedoch die Ausgabe in etwa so sein würde:

episode_summary_vw

+------------+-------------------------+ 
| epsiode_id | case_name    | 
+------------+-------------------------+ 
| 5   |  Eastwood & Joilee| 
| 6   |   Pitt & Aniston| 
| 7   |   Aniston & Pitt| 
+------------+-------------------------+ 

Für Oracle es wie LISTAGG Funktion sieht, was Sie wollen würde und für MySQL die GROUP_CONCAT Funktionen.In MySQL dann denke ich, das ist etwas aussehen würde:

CREATE VIEW episode_summary_vw as 
SELECT ep.episode_id, GROUP_CONCAT(p.surname SEPARATOR ' & ') 
FROM episode_person ep 
INNER JOIN person p on p.id = ep.person_id 
GROUP BY ep.episode_id; 
-- todo: needs limit to first 2 records 

Sobald wir einen Blick haben, dann können wir einfach die case_name Die Folge Entität Karte die @SecondaryTable Funktionalität von JPA mit:

@Entity 
@Table(name = "episodes") 
@SecondaryTable(name = "episode_summary_vw", primaryKeyJoinColumna = @PrimaryKeyJoinColumn(name="episode_id", reference_column_name="id")) 
public class Episode { 

    @Column(name ="case_name", table = "episode_summary_vw") 
    private String caseName; 
} 

Sie dann Filtern und sortieren Sie die Eigenschaft wie für jedes andere Feld:

if (pagination.getFilterBy().getMapOfFilters().get("caseName")!=null) { 

    where.and(qEpisode.caseName.containsIgnoreCase(pagination.getFilterBy(). 
     getMapOfFilters().get("caseName"))); 
} 
+0

Wird die Ansichtstabelle für jede Episode in der Datenbank erstellt? –

Verwandte Themen