Ich habe das ORM-Framework Mybatis verwendet und einige allgemeine Funktionen in Mybatis verwendet. Heutzutage gibt es in der Projektentwicklung ein Unternehmen, das die Abfrage von Feldern in bestimmten Tabellen durch jeden Benutzer und die Anzeige bestimmter Felder einschränken muss. Beispielsweise dürfen bestimmte Felder einer bestimmten Tabelle von Benutzern nicht abgefragt werden. In diesem Fall müssen Sie SQL erstellen, um den Tabellennamen und den Feldnamen dynamisch zu übergeben. Jetzt werde ich die Lösungen zusammenfassen. Ich hoffe, dass sie für Freunde hilfreich sind, die auf das gleiche Problem stoßen.
Dynamisches SQL ist eine der leistungsstarken Funktionen von mybatis. Bevor mybatis die SQL-Anweisung vorkompiliert, wird das SQL dynamisch analysiert und in ein BoundSql-Objekt umgewandelt. Machen wir uns zunächst mit der Verwendung von #{} und ${} in mybatis vertraut:
Im dynamischen SQL-Parsing-Prozess sind die Auswirkungen von #{} und ${} unterschiedlich:
#{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符。
Beispielsweise wird die folgende SQL-Anweisung
select * from user where name = #{name};
wie folgt geparst:
select * from user where name = ?;
Können Sie sehen, dass #{} als Parameterplatzhalter geparst wird? .
${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换
Zum Beispiel die folgende SQL-Anweisung:
select * from user where name = ${name};
Wenn wir den Parameter „sprite“ übergeben, wird die SQL wie folgt analysiert:
select * from user where name = "sprite";
Sie können die Vorschau sehen. Die SQL-Anweisung vor der Kompilierung enthält den Variablennamen nicht mehr.
Zusammenfassend lässt sich sagen, dass die Ersetzungsphase der Variablen von ${ } in der dynamischen SQL-Analysephase erfolgt, während die Ersetzungsphase der Variablen von #{ } im DBMS erfolgt.
Der Unterschied zwischen #{} und ${} lässt sich kurz wie folgt zusammenfassen:
#{} behandelt den eingehenden Parameter als Zeichenfolge und fügt ein Double hinzu Anführungszeichen für den Parameter
${} zeigt die eingehenden Parameter direkt in SQL an, ohne Anführungszeichen hinzuzufügen
#{}, was die SQL-Injection erheblich verhindern kann, ${ }SQL kann nicht verhindert werden Injektion
${} wurde vor der Vorkompilierung durch Variablen ersetzt, was das Risiko einer SQL-Injektion mit sich bringt. Die folgende SQL
select * from ${tableName} where name = ${name}
Wenn der eingehende Parameter tableName user ist; delete user; dann wird die SQL vor der Vorkompilierung zu:
select * from user; delete user; -- where name = ?;
--Die folgenden Aussagen funktionieren nicht als Kommentare. Meine Freunde und ich waren schockiert! ! ! Haben Sie gesehen, dass die ursprüngliche Abfrageanweisung heimlich eine SQL-Anweisung zum Löschen von Tabellendaten enthielt? ! ! Wenn Sie wichtige Dinge dreimal sagen, können Sie sich vorstellen, wie hoch das Risiko ist.
${} wird im Allgemeinen zum Übertragen von Tabellennamen, Feldnamen usw. der Datenbank verwendet
Versuchen Sie, ${} nicht zu verwenden, wo #{} verwendet werden kann
Kommen Sie zum Punkt und bestehen Sie. Aufgrund der obigen Analyse haben Sie meiner Meinung nach bereits einige Ideen, wie Tabellennamen und Feldnamen dynamisch aufgerufen werden können. Ein Beispiel lautet wie folgt:<select id="getUser" resultType="java.util.Map" parameterType="java.lang.String" statementType="STATEMENT"> select ${columns} from ${tableName} where COMPANY_REMARK = ${company} </select>Um einen dynamischen Aufruf von Tabellennamen und Feldnamen zu erreichen, kann keine Vorkompilierung verwendet werden und es muss „statementType="STATEMENT"" hinzugefügt werden.
statementType:STATEMENT(非预编译),PREPARED(预编译)或CALLABLE中的任意一个,这就告诉 MyBatis 分别使用Statement,PreparedStatement或者CallableStatement。默认:PREPARED。这里显然不能使用预编译,要改成非预编译。Zweitens ist in SQL der Wert der Variablen ${xxx} und nicht #{xxx}, da ${} die übergebenen Parameter zum Generieren von SQL direkt anzeigt. Beispielsweise sind die übergebenen Parameter von ${xxx} Zeichenfolgendaten. , müssen Sie Anführungszeichen hinzufügen, bevor die Parameter übergeben werden, z. B.:
String name = "sprite"; name = "'" + name + "'";