[JAVA] Erstellen Sie eine dynamische SQL-Anweisung mit MyBatis [Suche nach mehreren Wörtern zulassen]

Was du machen willst

Schlüsselwörter

Danach möchte ich eine ODER-Suche nach Schlüsselwörtern zusammen mit Kategorien durchführen (* Suche nach Elementen, die eines der durch ein Leerzeichen getrennten Schlüsselwörter enthalten **).

Umgebung

Betriebssystem verwendet-Windows 10 Verwendete Werkzeuge - Spring Tool Suite 4 4.6.2 Template Engine-Thymeleaf Framework-Mybatis

Ergebnis (Beschreibung der XML-Datei)

<select id="findByCategoryIdAndProductName" 
resultType="Dateipfad der entsprechenden Domain">
	
	SELECT * FROM item_table
	  WHERE cate_id = #{category}
      AND
	
	  <foreach collection="keywords" item="keyword" open="(" close=")" index="i" separator="" >
		<choose>
			<when test="i == 0">
				(item_name LIKE '%${keyword}%')
			</when>
			<otherwise>
				OR (item_name LIKE '%${keyword}%')
			</otherwise>
		</choose>
	  </foreach> 
</select>

Ich denke nicht, dass das Folgende für diejenigen notwendig ist, die damit verwechselt wurden. Wenn Sie keine Ahnung haben, was Sie tun, lesen Sie bitte weiter. Ich war mir nicht sicher, welche Vorteile die Verwendung von mybatis haben würde, daher beginne ich mit den Grundlagen.

Was ist SQL?

Eine der Computersprachen (** keine Programmiersprache **). Im Folgenden finden Sie die grundlegende CRUD-Funktionssyntax, die beim Herstellen einer Verbindung zur Datenbank verwendet wird.

** ERSTELLEN **

INSERT INTO Tabellenname(Spaltenname, Spaltenname,...) values('Daten einfügen', 'Daten einfügen', ...);
INSERT INTO Tabellenname VALUES('Daten einfügen', 'Daten einfügen', ...),('Daten einfügen', 'Daten einfügen', ...);

** LESEN (Referenz) **

SELECT Spaltenname FROM Tabellenname;

** UPDATE **

UPDATE Tabellenname SET Spaltenname= 'Inhalt überschreiben';

** LÖSCHEN **

DELETE FROM Tabellenname;

Fügen Sie am Ende dieser Sätze "WHERE" hinzu, um detailliertere Daten anzugeben. Da es von der Hauptzeile abweicht, werde ich hier für SQL anhalten.

Was ist mein Batis?

Laut der [offiziellen Website] von MyBatis (https://mybatis.org/mybatis-3/ja/)

Was ist MyBatis?

MyBatis ist ein hervorragendes Persistenz-Framework für benutzerdefiniertes SQL, gespeicherte Prozeduren und erweiterte Zuordnung. Durch die Verwendung von MyBatis ist es fast nicht erforderlich, Code zu schreiben, der JDBC direkt verarbeitet, oder Abfrageargumente und Abfrageergebnisse manuell festzulegen. Sie können MyBatis konfigurieren und Java-Objekten mithilfe von XML oder Anmerkungen Datenbankeinträge zuordnen.

Grob gesagt scheint es ein ** Framework zu sein, das beim Schreiben von komplexem SQL ** nützlich ist.

Hauptthema

Bereiten Sie zunächst auf dem Controller eine Methode vor, um das von der Benutzerseite eingegebene Suchschlüsselwort in das Anfangsformular zu bearbeiten.

Schlüsselwortverarbeitung

Suchschlüsselwörter werden in der Formularklasse als "String-Schlüsselwörter" deklariert.

Die Geschichte ist ein wenig anders, aber die Formularklasse ist eine Datei, die vorbereitet wird, wenn Sie Informationen in einem Stapel senden möchten. Es gibt nur Setter und Getter im Inneren.

public String search(SampleForm f) {
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
}

Die Methode replaceAll verwendet zwei Argumente und ersetzt gleichzeitig eine bestimmte Zeichenfolge. Die erste Methode replaceAll ("", "") konvertiert einen Raum voller Breite in einen Raum halber Breite (edit ①). Bei der zweiten Methode replaceAll ("\\ s {2,}", "") werden zwei oder mehr Leerzeichen mit halber Breite in ein Leerzeichen mit halber Breite konvertiert (edit ②). Die dritte Methode, trim (), entfernt die führenden und nachfolgenden Leerzeichen.

Informationen zur replaceAll-Methode

Sie können das erste sehen, aber für das zweite möchte ich eine Bedingung von "zwei oder mehr" hinzufügen, also verwende ich Metazeichen.

Referenz: Beispielsammlung für reguläre Ausdrücke

Informationen zur SQL-Anweisung für die Suche

Die Frage, welche Art von SQL überhaupt geschrieben werden soll.

"ODER nach einem Wort suchen, das ein bestimmtes Schlüsselwort enthält" lautet beispielsweise ** Wenn Sie nach den Schlüsselwörtern "ai", "ue" und "o" suchen, können Sie irgendwo in der Zeichenfolge "ai", "ue" oder "o" finden. Die Bewegung des Extrahierens aller darin enthaltenen Wörter **.

Zunächst die Anweisung, die alle Werte extrahiert, die das Wort A enthalten

SELECT *FROM Tabellenname WHERE Spaltenname LIKE'%A%';

Der Satz, der alle Werte einschließlich der Wörter "a", "i" und "u" extrahiert.

SELECT *FROM Tabellenname WO(Spaltenname LIKE'%Ai%')
                           OR (Spaltenname LIKE'%über%')
                           OR (Spaltenname LIKE'%Oh%');

Referenz: [So legen Sie mehrere Suchbedingungen für eine Spalte fest](https://docs.microsoft.com/ja-jp/sql/ssms/visual-db-tools/specify-multiple-search-conditions -für-eine-Spalte-visuelle-Datenbank-Tools? view = sql-server-ver15) Es ist mir gelungen, ohne Klammern () zu setzen, daher kann beides in Ordnung sein.

Ich war hier in Schwierigkeiten

Möglicherweise gibt es kein Suchschlüsselwort oder mehrere Suchschlüsselwörter. Außerdem weiß ich nicht, wie viele eingegeben werden. Wenn dies keine Suche mit der LIKE-Klausel ist, sondern eine Übereinstimmungsbedingung (=), scheint es möglich zu sein, sie alle mit IN zu verbinden, aber diesmal ist es unmöglich.

Der gleiche Prozess für mehrere Dinge ist ein iterativer Prozess, aber Java kann nur den in% enthaltenen "ai" -Teil ausführen.

Lösung

Dies ist eine Lösung, die durchgeführt werden kann, da das Framework MyBatis ist und ** Sie eine iterative Verarbeitung schreiben können, indem Sie Bedingungen in der SQL-Anweisung festlegen **. Dieses Mal verwenden wir <foreach> <choose> <when> <otherwise>.

Übrigens gibt es andere Tags wie <if> <trim> <where> <set> `.

foreach So verwenden Sie das Tag "".

Erstens ist es als wichtige Voraussetzung für andere Programmiersprachen üblich Die ** foreach-Anweisung **, auch als ** erweiterte for-Anweisung ** bezeichnet, nimmt die Werte ** mehrerer Elemente wie Arrays und Sammlungen in der richtigen Reihenfolge heraus und verarbeitet sie **.

<foreach item="item" index="index" collection="list" open="(" close=")" separator=",">
     <!--Schreiben Sie hier den Vorgang, den Sie wiederholen möchten-->
</foreach>

Geben Sie vor der Beschreibung des Prozesses sechs Eigenschaften an. In einigen Fällen ist ein Öffnen und Schließen nicht erforderlich.

Dieses Mal werden die Schlüsselwörter in einer Variablen namens Schlüsselwörter gespeichert, und jeder Wert wird in der foreach-Anweisung als Schlüsselwort angegeben. Außerdem wird bei der Suche die Suche zusammen mit der Kategorie ausgeführt, sodass der Umriss der SELECT-Anweisung folgendermaßen aussieht.

SELECT * FROM item_table
  WHERE cate_id = #{category} AND
	
	<foreach collection="keywords" item="keyword" open="(" close=")" index="i" separator="" >
	  <!--Schreiben Sie hier den Verarbeitungsinhalt-->	
	</foreach>
Ruhig: Müssen Sie öffnen und schließen?

Aus der Schlussfolgerung ist es diesmal notwendig.

Wenn die Kategorie beispielsweise 1 ist und "Ai" und "Ue" als Suchschlüsselwörter angegeben sind, muss der gesamte foreach-Prozess in Klammern eingeschlossen werden.

SELECT * FROM item_table 
WHERE cate_id =1 UND Spaltenname LIKE'%Ai%'ODER Spaltenname LIKE'%über%'

In einem solchen Prozess werden AND (und) und OR (oder) verwechselt, und die Maschine kann nicht bestimmen, unter welchen Bedingungen die Daten extrahiert werden sollen, was zu einem Fehler führt.

SELECT * FROM item_table 
WHERE cate_id = 1 AND (Spaltenname LIKE'%Ai%' OR Spaltenname LIKE'%über%')

Sie können feststellen, ob es ordnungsgemäß in Klammern () eingeschlossen ist.

Übrigens, wenn das Suchwort nichts enthält

SELECT * FROM item_table WHERE cate_id = 1 AND (Spaltenname LIKE'%%')

Dies ist der Prozess. Es gibt kein Problem, da kein Fehler vorliegt.

choose、when、otherwise Das <when> Tag ist ** if ** und das <otherwise> Tag ist ** else **. Der Unterschied zum <if> -Tag besteht darin, ob eine Verarbeitung erforderlich ist, die einer anderen entspricht, oder verwenden Sie sie daher je nach Fall ordnungsgemäß.

Wenn Sie <when> <otherwise> verwenden, schließen Sie das Ganze in das Tag <choose> ein. Verwenden Sie bei Verwendung des Tags <if> nicht das Tag <Wählen>.

Die allgemeine if-Anweisung lautet if (bedingter Ausdruck), aber der Teil, der dem bedingten Ausdruck entspricht, wird durch ** test = "" ** angegeben.

Letzte SQL-Anweisung

Um diesen Code zu betrachten, schauen wir uns noch einmal die SELECT-Anweisung an.

SELECT *FROM Tabellenname WO(Spaltenname LIKE'%Ai%')
                           OR (Spaltenname LIKE'%über%')
                           OR (Spaltenname LIKE'%Oh%');

Auf diese Weise möchte ich das ** erste Schlüsselwort ** in% einschließen und für die ** nachfolgenden Schlüsselwörter ** am Anfang ein ODER hinzufügen und das Schlüsselwort in% einfügen. Geben Sie den Satz von ↑ im bedingten Ausdruck von wann an.

<select id="findByCategoryIdAndProductName" 
resultType="Dateipfad der entsprechenden Domain">
  SELECT * FROM item_table
    WHERE cate_id = #{category}
    AND	
   <!--Extrahieren Sie Werte aus Schlüsselwörtern in der angegebenen Reihenfolge und wiederholen Sie die Verarbeitung-->
    <foreach collection="keywords" item="keyword" open="(" close=")" index="i" separator="" >

      <!--Ich möchte wann und anderweitig verwenden, also lege es in wähle-->
	  <choose>
        <!--Verarbeitung bei Indexnummer 0-->
		<when test="i == 0">
			(item_name LIKE '%${keyword}%')
		</when>
        <!--Andernfalls-->
        <!--Verarbeitung durch Hinzufügen von OR vor der bedingten Anweisung-->	
		<otherwise>
			OR (item_name LIKE '%${keyword}%')
		</otherwise>
	  </choose>
  </foreach>
</select>

Mapper-Dateieinstellungen

Die XML-Datei kann die Verarbeitung ausführen, die durch das Vorhandensein der gleichnamigen Mapper-Datei beschrieben wird (beim Umdrehen kann der Beschreibungsinhalt von XX Mapper.java durch Beschreibung von XX Mapper.xml vereinfacht werden).

Beschreiben Sie in der gleichnamigen Mapper-Klasse Folgendes.

Gleicher Name wie XML-Datei.java


//Import weggelassen

@Mapper
public interface 〇〇Mapper {
    List<MstProduct> findByCategoryIdAndProductName(
    @Param("category") long category,
    @Param("keywords") String[] keywords);
    //Da es in XML als Sammlung behandelt wird, handelt es sich nicht um einen String-Typ, sondern um einen String[]Mach eine Form
}

FindBy ~ ist ein Anweisungsname, mit dem die in der Java-Datei geschriebene Methode der SQL-Anweisung in der XML-Datei zugeordnet wird.

Holen Sie sich Suchergebnisse mit dem Controller

Die eingangs eingeführte Beschreibung der Steuerung reicht nicht aus. Nun, das einzige, was ich gerade getan habe, ist, dass ich die Schlüsselwörter auf verschiedene Arten bearbeitet habe, also ist es natürlich.

Informationen bekommen

public String search(SampleForm f) {
  //Es werden nur Schlüsselwörter deklariert
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
}

Ich werde die Beschreibung hier hinzufügen. Zunächst nur die Funktion zum Erfassen von Informationen. Dieses Mal wird Tymeleaf als Vorlagen-Engine übernommen, das Attribut wird in HTML als th: each = "item: $ {items}" bezeichnet und die Informationen jeder Spalte werden ausgegeben. Die Geschichte hier ist zu schwer, also google sie auf Tymeleaf.

python


//Import, Klasse und andere Methoden weglassen

public String search(SampleForm f, Model m) {
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
  //Holen Sie sich eine Liste mit Produktinformationen
  List<Item> items;
  
  //search.In HTML"items"Senden Sie Informationen zur Artikelliste an die Zeichenfolge
  m.addAttribute("items", items);
  
  //Es gibt noch keine Suchfunktion
  //search.Zu HTML
  return "search";
}

Suchfunktion implementiert

Die Beschreibung der Suchfunktion wurde hinzugefügt.

python


//Import, Klasse und andere Methoden weglassen

public String search(SampleForm f, Model m) {
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
  //Holen Sie sich eine Liste mit Produktinformationen
  List<Item> items;
  
  //Suchvorgang
  //Mit anderen Worten: apperMapper.Übergeben Sie Informationen zu Kategorien und Schlüsselwörtern an Java
  //Außerdem 〇〇Mapper.Übergeben Sie Informationen an XML, wählen Sie SELECT und weisen Sie das Ergebnis der Artikelliste zu
  items = 〇〇Mapper.findByCategoryIdAndProductName(
          f.getCategory(),
          keywords);

  //search.In HTML"items"Senden Sie Informationen zur Artikelliste an die Zeichenfolge
  m.addAttribute("items", items);
  
  //search.Zu HTML
  return "search";
}

Suchfunktion implementiert. Dies ist jedoch nicht vollständig.

In diesem Zustand sind Schlüsselwörter nur die Suchschlüsselwörter, die durch ein Leerzeichen mit halber Breite verbunden sind. Sie können daher nicht in foreach wiederholt werden, und ein Kompilierungsfehler tritt aufgrund einer Typinkongruenz auf.

Ordnen Sie Schlüsselwörter

python


//Import, Klasse und andere Methoden weglassen

public String search(SampleForm f, Model m) {
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
  //Holen Sie sich eine Liste mit Produktinformationen
  List<Item> items;
  
  //Suchvorgang
  //Mit anderen Worten: apperMapper.Übergeben Sie die Schlüsselwortinformationen an Java
  //Außerdem 〇〇Mapper.Übergeben Sie Informationen an XML, wählen Sie SELECT und weisen Sie das Ergebnis der Artikelliste zu
  items = 〇〇Mapper.findByCategoryIdAndProductName(
          f.getCategory(),
          //Teilen Sie die Zeichenfolge mit der Split-Methode mit einem Leerzeichen halber Breite und geben Sie sie als Array zurück
          keywords.split(" "));

  //search.In HTML"items"Senden Sie Informationen zur Artikelliste an die Zeichenfolge
  m.addAttribute("items", items);
  
  //search.Zu HTML
  return "search";
}

Dies ist abgeschlossen. Hurra

python



public String search(SampleForm f, Model m) {
  String keywords = f.getKeywords().replaceAll(" ", " ").replaceAll("\\s{2,}", " ").trim();
  List<Item> items;
  items = 〇〇Mapper.findByCategoryIdAndProductName(f.getCategory(), keywords.split(" "));

  m.addAttribute("items", items);
  
  return "search";
}

Recommended Posts

Erstellen Sie eine dynamische SQL-Anweisung mit MyBatis [Suche nach mehreren Wörtern zulassen]
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