[JAVA] Wie man mit der Generierung dynamischer SQL-Abfragen ein wenig knifflig baut

Hintergrund

Ich habe den Code eines Neulings überprüft (PG-Verlauf ca. 3 Wochen?) Und eine leicht interessante SQL-Abfrage generiert. Teilen Sie also die Geschichte mit. Ich spreche über die Verwendung einer Art OP-Mapper oder Doma, aber lassen Sie das weg.

Annahme

Ich möchte, dass auf dem Suchbildschirm mehrere Eingabefelder vorhanden sind und die vom Benutzer eingegebenen Elemente zu den SQL-Suchbedingungen hinzugefügt werden.

Sofern Sie keinen Active Record-ähnlichen OR-Mapper verwenden, verwenden Sie keine 2-Wege-SQL-Bibliothek wie Doma.

Wenn Sie Lust dazu haben, können Sie SQL in eine externe Datei ausschneiden, aber ich denke, dass die übliche Idee für Anfänger darin besteht, Strings dynamisch zu generieren und SQL zu erstellen.

Daher würden Sie normalerweise SQL-Abfragen mit Zeichenfolgenverknüpfungen in Ihrem Code generieren.

** Dieses Mal Schema: ** http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05780-02/scripts.htm#Cihgfecd

Beispiel: Eine Abfrage, wenn Sie in der Mitarbeitertabelle nach "Verkäufe sind in der Jobkategorie enthalten" und "Gehalt beträgt 6 Millionen Yen oder mehr" suchen möchten. Lassen Sie mich die Escape-Einstellung in der Like-Klausel weglassen.

SQL, das Sie generieren möchten


SELECT
 em.EMPLOYEE_ID
, em.FIRST_NAME
, em.LAST_NAME
FROM
  EMPLOYEES em
, INNER JOIN JOB_HISTORY jh on (em.EMPLOYEE_ID = jh.EMPLOYEE_ID)
, INNER JOIN JOBS jb on (jh.JOB_ID = jb.JOB_ID)
WHERE 1 = 1
AND CURRENT_DATE BETWEEN jh.START_DATE AND jh.END_DATE
AND jb.JOB_TITLE LIKE '%' || ? || '%';     --Ich möchte es der Bedingung hinzufügen, wenn es vom Benutzer angegeben wird
AND jb.SALARY >= ?                         --Ich möchte es der Bedingung hinzufügen, wenn es vom Benutzer angegeben wird
;

Normalerweise wird das Vorhandensein oder Fehlen einer Zeichenkettenkombination häufig vom Vorhandensein oder Fehlen des Werts verzweigt. Abgesehen von der Verwendung von StringBuilder weiß ich es nicht.

python


String sql = ~ ; //Kürzung. Annahme von SQL bis zur ersten Zeile der WHERE-Klausel.

if (jobTitle != null && jobTitle.length >= 0) {
  sql += "AND jb.JOB_TITLE LIKE '%' || ? || '%'"
}

if (minSalary != null && minSalaly.length >= 0) {
  sql += "AND jb.SALARY >= ?"
}

Ein Neuling tat dies jedoch.

jobTitleComment = "";
minSalaryComment = "";
if (jobTitle != null && jobTitle.length >= 0) {
 jobTitleComment = "--";
}

if (minSalary != null && minSalaly.length >= 0) {
 minSalaryComment = "--";
}

String sql = "SELECT"
+ " em.EMPLOYEE_ID"
+ ", em.FIRST_NAME"
+ ", em.LAST_NAME"
+ "FROM"
+ "  EMPLOYEES em"
+ ", INNER JOIN JOB_HISTORY jh on (em.EMPLOYEE_ID = jh.EMPLOYEE_ID)"
+ ", INNER JOIN JOBS jb on (jh.JOB_ID = jb.JOB_ID)"
+ "WHERE 1 = 1"
+ "AND CURRENT_DATE BETWEEN jh.START_DATE AND jh.END_DATE"
+ jobTitleComment + "AND jb.JOB_TITLE LIKE '%' || ? || '%'"  //Punkt
+ minSalaryComment + "AND jb.SALARY >= ?"                     //Punkt
;

Ich konnte die Absicht nicht verstehen, als ich Pat ansah, und sie blieb einige Sekunden lang hängen, aber als ich genau hinschaute, konnte ich sie nicht verstehen. Ich versuche zu wechseln, ob SQL-Suchbedingungen verwendet werden sollen, wobei "-" einen Kommentar angibt.

Ein Beispiel für die SQL-Generierung nach der Ausführung, wenn keine der beiden Bedingungen festgelegt ist, lautet beispielsweise wie folgt.

Wenn die Suchbedingung nicht festgelegt ist


SELECT
 em.EMPLOYEE_ID
, em.FIRST_NAME
, em.LAST_NAME
FROM
  EMPLOYEES em
, INNER JOIN JOB_HISTORY jh on (em.EMPLOYEE_ID = jh.EMPLOYEE_ID)
, INNER JOIN JOBS jb on (jh.JOB_ID = jb.JOB_ID)
WHERE 1 = 1
AND CURRENT_DATE BETWEEN jh.START_DATE AND jh.END_DATE
-- AND jb.JOB_TITLE LIKE '%' || ? || '%'  /*★ Beide werden auskommentiert*/
-- AND jb.SALARY >= ?                                          /*★ Beide werden auskommentiert*/
;

Da die Suchbedingung leer ist, wird die Verfeinerungsbedingung der Where-Klausel auskommentiert und ungültig gemacht.

Weiter ist ein Beispiel für die Generierung, wenn nur der Jobname festgelegt ist.

Wenn nur der Jobname festgelegt ist


SELECT
 em.EMPLOYEE_ID
, em.FIRST_NAME
, em.LAST_NAME
FROM
  EMPLOYEES em
, INNER JOIN JOB_HISTORY jh on (em.EMPLOYEE_ID = jh.EMPLOYEE_ID)
, INNER JOIN JOBS jb on (jh.JOB_ID = jb.JOB_ID)
WHERE 1 = 1
AND CURRENT_DATE BETWEEN jh.START_DATE AND jh.END_DATE
AND jb.JOB_TITLE LIKE '%' || 'Der Umsatz' || '%'  /*Dies ist gültig*/
-- AND jb.SALARY >= '??'                      /*Dies bleibt auskommentiert*/
;

Wenn die Suchbedingung vorhanden ist, ist die entsprechende Verfeinerungsbedingung in der Where-Klausel gültig. Ich fand es überraschend leicht zu sehen.

Zusammenfassung

Recommended Posts

Wie man mit der Generierung dynamischer SQL-Abfragen ein wenig knifflig baut
So erstellen Sie eine Rails 6-Umgebung mit Docker
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)
Erstellen Sie mit Spring Boot eine einfache Such-App
Erstellen Sie einen Spielplatz mit Xcode 12
Ich habe versucht, eine flexible ODER-Zuordnung mit MyBatis Dynamic SQL zu implementieren
Erstellen Sie eine Restaurant-Such-App mit der IBM Watson + Guru Navi-API (mit Quelle).
Wie man mit der Generierung dynamischer SQL-Abfragen ein wenig knifflig baut
So erstellen Sie eine API mit GraphQL und Rails
[Rails] So erstellen Sie eine Umgebung mit Docker
So erstellen Sie eine Pytorch-Umgebung unter Ubuntu
So springen Sie von Eclipse Java zu einer SQL-Datei
So erstellen Sie eine Docker-Umgebung mit Gradle for IntelliJ
[Rails] [Docker] Kopieren und Einfügen ist in Ordnung! So erstellen Sie eine Rails-Entwicklungsumgebung mit Docker
So löschen Sie ein mit Rails erstelltes new_record-Objekt
So generieren Sie manuell ein JWT mit Knock in Rails
[So fügen Sie ein Video mit Rails in haml ein]
So beenden Sie Docker für Mac und erstellen eine Docker-Entwicklungsumgebung mit Ubuntu + Vagrant
So erstellen Sie eine Java-Entwicklungsumgebung mit VS Code
Abfragen von Arrays in jsonb mit Rails + postgres
Wie man android-midi-lib baut
[Java] So unterbrechen Sie eine Zeile mit StringBuilder
So reduzieren Sie die Programmlast ein wenig, wenn Sie Zeichen mit JAVA kombinieren
So machen Sie einen Screenshot mit dem Android Studio-Emulator
So fordern Sie mit jMeter eine CSV-Datei als JSON an
[Ruby] So teilen Sie jede GraphQL-Abfrage in Dateien auf
So erstellen Sie mit Docker ~ Express ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
Ruby mit AtCoder lernen 13 So erstellen Sie ein zweidimensionales Array
So verschieben Sie eine andere Klasse mit einer Schaltflächenaktion einer anderen Klasse.
Hinweise zum Erstellen von Jitsi Meet on Azure mit Docker-Compose
Zuordnung zu einer Klasse mit einem Wertobjekt in How to My Batis
So verbinden Sie eine Tabelle ohne DBFlute und SQL
So richten Sie einen Proxy mit Authentifizierung in Feign ein
So registrieren Sie sich mit Tomcat als Kunde in Square
Wie hinterlasse ich einen Kommentar?
Wie man mit html.erb nummeriert (nummeriert)
So aktualisieren Sie mit activerecord-import
So fügen Sie ein Video ein
So erstellen Sie eine Methode
So brechen Sie das Zusammenführen von Zellen innerhalb eines bestimmten Bereichs mit dem POI ab
So erstellen Sie eine JAR-Datei ohne Abhängigkeiten in Maven
[Rails 6] So erstellen Sie mit cocoon einen dynamischen Formular-Eingabebildschirm
So erstellen Sie mit Docker ~ MySQL ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
Ich habe versucht, eine flexible ODER-Zuordnung mit MyBatis Dynamic SQL zu implementieren
Versuchen Sie, mit JRuby eine plattformübergreifende Anwendung zu erstellen (Generierung von JAR-Dateien).
So benennen Sie ein Modell mit externen Schlüsseleinschränkungen in Rails um
So öffnen Sie eine Skriptdatei von Ubuntu mit VS-Code
So erstellen Sie eine Rails + Vue + MySQL-Umgebung mit Docker [neueste Version 2020/09]
So erstellen Sie mit Docker ~ Sequelize ~ eine [TypeScript + Vue + Express + MySQL] -Umgebung
Sie können die Version der Projektfacette nicht von einem dynamischen Webmodul in x.x ändern. Wie man damit umgeht
Erstellen eines Java-Projekts mit Gradle
Erstellen Sie mit Docker eine Node.js-Umgebung
Wie fange ich mit schlank an?