iBATIS - Dynamisches SQL
Dynamisches SQL ist eine sehr leistungsstarke Funktion von iBATIS. Manchmal müssen Sie das WHERE-Klauselkriterium basierend auf dem Status Ihres Parameterobjekts ändern. In solchen Situationen bietet iBATIS eine Reihe dynamischer SQL-Tags, die in zugeordneten Anweisungen verwendet werden können, um die Wiederverwendbarkeit und Flexibilität von SQL zu verbessern.
Die gesamte Logik wird mithilfe einiger zusätzlicher Tags in eine XML-Datei eingefügt. Das folgende Beispiel zeigt, wie die SELECT-Anweisung auf zwei Arten funktioniert:
- Wenn Sie eine ID übergeben, werden alle dieser ID entsprechenden Datensätze zurückgegeben.
- Andernfalls werden alle Datensätze zurückgegeben, in denen die Mitarbeiter-ID auf NULL gesetzt ist.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Employee">
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNull property="id">
id IS NULL
</isNull>
<isNotNull property="id">
id = #id#
</isNotNull>
</dynamic>
</select>
</sqlMap>
Sie können eine Bedingung mit dem Tag <isNotEmpty> wie folgt überprüfen. Hier würde eine Bedingung nur hinzugefügt, wenn eine übergebene Eigenschaft nicht leer ist.
..................
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotEmpty property="id">
id = #id#
</isNotEmpty>
</dynamic>
</select>
..................
Wenn Sie eine Abfrage wünschen, bei der wir eine ID und / oder den Vornamen eines Mitarbeiters auswählen können, lautet Ihre SELECT-Anweisung wie folgt:
..................
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotEmpty prepend="AND" property="id">
id = #id#
</isNotEmpty>
<isNotEmpty prepend="OR" property="first_name">
first_name = #first_name#
</isNotEmpty>
</dynamic>
</select>
..................
Dynamisches SQL-Beispiel
Das folgende Beispiel zeigt, wie Sie eine SELECT-Anweisung mit dynamischem SQL schreiben können. Bedenken Sie, wir haben die folgende EMPLOYEE-Tabelle in MySQL -
CREATE TABLE EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
Nehmen wir an, diese Tabelle enthält nur einen Datensatz wie folgt:
mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1 | Zara | Ali | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)
Mitarbeiter POJO Klasse
Um eine Leseoperation durchzuführen, lassen Sie uns eine Employee-Klasse in Employee.java wie folgt haben:
public class Employee {
private int id;
private String first_name;
private String last_name;
private int salary;
/* Define constructors for the Employee class. */
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.first_name = fname;
this.last_name = lname;
this.salary = salary;
}
/* Here are the method definitions */
public int getId() {
return id;
}
public String getFirstName() {
return first_name;
}
public String getLastName() {
return last_name;
}
public int getSalary() {
return salary;
}
} /* End of Employee */
Employee.xml-Datei
Um die SQL-Zuordnungsanweisung mit iBATIS zu definieren, fügen wir das folgende modifizierte <select> -Tag in Employee.xml hinzu und definieren innerhalb dieser Tag-Definition eine "id", die in IbatisReadDy.java zum Ausführen der Dynamic SQL SELECT-Abfrage verwendet wird Datenbank.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Employee">
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotNull property="id">
id = #id#
</isNotNull>
</dynamic>
</select>
</sqlMap>
Die obige SELECT-Anweisung würde auf zwei Arten funktionieren:
Wenn Sie eine ID übergeben, werden Datensätze zurückgegeben, die dieser ID entsprechen. Andernfalls werden alle Datensätze zurückgegeben.
IbatisReadDy.java-Datei
Diese Datei verfügt über eine Logik auf Anwendungsebene zum Lesen von bedingten Datensätzen aus der Employee-Tabelle.
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class IbatisReadDy{
public static void main(String[] args) throws IOException,SQLException{
Reader rd=Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient smc=SqlMapClientBuilder.buildSqlMapClient(rd);
/* This would read all records from the Employee table.*/
System.out.println("Going to read records.....");
Employee rec = new Employee();
rec.setId(1);
List <Employee> ems = (List<Employee>)
smc.queryForList("Employee.findByID", rec);
Employee em = null;
for (Employee e : ems) {
System.out.print(" " + e.getId());
System.out.print(" " + e.getFirstName());
System.out.print(" " + e.getLastName());
System.out.print(" " + e.getSalary());
em = e;
System.out.println("");
}
System.out.println("Records Read Successfully ");
}
}
Kompilieren und Ausführen
Hier sind die Schritte zum Kompilieren und Ausführen der oben genannten Software. Stellen Sie sicher, dass Sie PATH und CLASSPATH richtig eingestellt haben, bevor Sie mit der Kompilierung und Ausführung fortfahren.
- Erstellen Sie Employee.xml wie oben gezeigt.
- Erstellen Sie Employee.java wie oben gezeigt und kompilieren Sie es.
- Erstellen Sie IbatisReadDy.java wie oben gezeigt und kompilieren Sie es.
- Führen Sie die IbatisReadDy-Binärdatei aus, um das Programm auszuführen.
Sie würden das folgende Ergebnis erhalten und ein Datensatz aus der Tabelle EMPLOYEE gelesen.
Going to read records.....
1 Zara Ali 5000
Record Reads Successfully
Versuchen Sie das obige Beispiel, indem Sie bestehen nullals smc.queryForList ("Employee.findByID", null) .
iBATIS OGNL-Ausdrücke
iBATIS bietet leistungsstarke OGNL-basierte Ausdrücke, um die meisten anderen Elemente zu eliminieren.
- if-Anweisung
- Wählen Sie, wann, sonst Aussage
- wo Aussage
- foreach Statement
Die if-Anweisung
In dynamischem SQL wird am häufigsten ein Teil einer where-Klausel bedingt eingeschlossen. Zum Beispiel -
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<if test="title != null">
AND title like #{title}
</if>
</select>
Diese Anweisung bietet eine optionale Funktionalität für die Textsuche. Wenn Sie keinen Titel übergeben, werden alle aktiven Blogs zurückgegeben. Wenn Sie jedoch einen Titel übergeben, wird nach einem Titel mit dem angegebenen Titel gesuchtlike Bedingung.
Sie können mehrere einschließen if Bedingungen wie folgt -
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null">
AND author like #{author}
</if>
</select>
Die Anweisungen wählen, wann und ansonsten
iBATIS bietet a chooseElement, das der switch-Anweisung von Java ähnelt. Es hilft, nur einen Fall unter vielen Optionen auszuwählen.
Das folgende Beispiel würde nur nach Titel suchen, wenn einer angegeben ist, und nur nach Autor, wenn einer angegeben ist. Wenn beides nicht angegeben ist, werden nur vorgestellte Blogs zurückgegeben -
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author like #{author}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
Die where-Anweisung
Schauen Sie sich unsere vorherigen Beispiele an, um zu sehen, was passiert, wenn keine der Bedingungen erfüllt ist. Sie würden mit einem SQL enden, das so aussieht -
SELECT * FROM BLOG
WHERE
Dies würde fehlschlagen, aber iBATIS hat eine einfache Lösung mit einer einfachen Änderung, alles funktioniert gut -
<select id="findActiveBlogLike" parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null>
AND author like #{author}
</if>
</where>
</select>
Das whereDas Element fügt nur dann ein WHERE ein , wenn die enthaltenen Tags Inhalte zurückgeben. Wenn dieser Inhalt mit UND oder ODER beginnt , kann er ihn außerdem entfernen.
Die foreach-Erklärung
Mit dem foreach-Element können Sie eine Sammlung angeben und Element- und Indexvariablen deklarieren, die im Hauptteil des Elements verwendet werden können.
Außerdem können Sie öffnende und schließende Zeichenfolgen angeben und ein Trennzeichen zwischen den Iterationen einfügen. Sie können eine bauenIN Bedingung wie folgt -
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>