<jsptutorial />

Die sql-Bibliothek


Mit der sql-Bibliothek wurde die Möglichkeit geschaffen, direkt in JSPs einfach auf Datenbanken zuzugreifen. Das erinnert mich an alte ColdFusion-Tage, als man dies bereits mit den <cfquery>, <cfinsert>, <cfupdate>-Tags konnte. Allerdings ist es schon sehr verwunderlich, dass diese Bibliothek den Weg in die JSTL geschafft hat. Da wird einerseits (in meinen Augen völlig zurecht) immer wieder die Notwendigkeit eines sauberen Designs mit einer Trennung von Präsentationsschicht und Geschäftslogik betont, andererseits aber mit diesen Tags das direkte Durchgreifen über alle Schichtgrenzen hinweg auf die DB ermöglicht. Wir lassen dies hier einfach im Raum stehen und halten uns mit unseren üblichen Kommentaren für heute zurück. Wir beschränken uns darauf, im Folgenden alle Tags vorzustellen und überlassen es der geneigten Leserin, über Sinn oder Unsinn dieser Tags nachzudenken ;-)

TagBodyBedeutung
transactionJSPStellt für die eingeschlossenenen SQL-Tags eine Transaktionsklammer bereit
queryJSPFührt eine Datenbank-Abfrage durch (SELECT)
updateJSPFührt Änderungsanfragen an die Datenbank aus (INSERT, UPDATE, DELETE)
paramJSPSetzt einen Anfrageparameter auf den angegebenen Wert
dateParamJSPSetzt einen Datums- und/oder Zeitanfrageparameter auf den angegebenen Wert. Der Wert muss vom Typ java.util.Date sein
setdataSourceleerLegt ein javax.sql.DataSource-Objekt in einer Variablen ab

Zum SeitenanfangZum Seitenanfang

<sql:transaction>

AttributPflichtfeldBedeutung
dataSourceneinGibt die DataSource an, die verwendet werden soll. Der Wert muss entweder eine Variable vom Typ Datasource sein oder ein String, der einen JNDI-Pfad oder die JDBC-DriverManager-Parameter enthält.
isolationneinDer gewünschte Isolationslevel. Wenn dieser leer gelassen wird, ist es der standardmäßig für diese Datenquelle definierte. Mögliche Werte sind "read_uncommitted", "read_committed", "repeatable_read" und "serializable"


Bildet eine Transaktionsklammer für <sql:query> und <sql:update>-Tags. Die möglichen Attribute sind nur nötig, wenn man mehrere Datenquellen nutzt und/oder bewusst unterschiedliche Transaktionslevel für eine Datasource nutzen will.

Zum SeitenanfangZum Seitenanfang

<sql:query>

AttributPflichtfeldBedeutung
varjaDer Name, unter dem das Ergebnis der SQL-Abfrage abgelegt werden soll
scopeneinDer gewünschte Gültigkeitsbereich für die unter dem Attribut "var" angegebene Variable
dataSourceneinGibt die DataSource an, die verwendet werden soll. Der Wert muss entweder eine Variable vom Typ Datasource sein oder ein String, der einen JNDI-Pfad oder die JDBC-DriverManager-Parameter enthält.
sqlneinDas abzusetzende Statement. Wird dieses Attribut nicht genutzt, so ist der Body des Tags für das gewünschte SQL-Statement zu nutzen
startRowneinDie erste gewünschte Zeile des Abfrageergebnisses. Für seitenweise Darstellung geeignet
maxRowsneinDie maximale Anzahl der Ergebnisse, die die Abfrage liefern soll


Dieser Tag wird für Anfragen an die Datenbank genutzt. Das Ergebnis wird in einem Objekt vom Typ javax.servlet.jsp.jstl.sql.Result abgelegt. Der Name, unter dem dieses Objekt abgelegt werden soll, bildet das einzige Pflicht-Attribut des Tags.

Zum SeitenanfangZum Seitenanfang

<sql:update>

AttributPflichtfeldBedeutung
varneinDer Name, unter dem das Ergebnis der SQL-Abfrage abgelegt werden soll. Das Ergebnis ist vom Typ java.lang.Integer und gibt die Anzahl der veränderten bzw. neu hinzugefügten Reihen in der veränderten Tabelle an
scopeneinDer gewünschte Gültigkeitsbereich für die unter dem Attribut "var" angegebene Variable
dataSourceneinGibt die DataSource an, die verwendet werden soll. Dies muss entweder eine Variable vom Typ Datasource sein oder ein String, der einen JNDI-Pfad oder die JDBC-DriverManager-Parameter enthält.
sqlneinDas abzusetzende Statement. Wird dieses Attribut nicht genutzt, so ist der Body des Tags für das gewünschte SQL-Statement zu nutzen


Mit dem Update-Tag werden Veränderungen an der DB vorgenommen. Auch wenn der Tag <sql:update> lautet, so dient dieser Tag neben UPDATE-Statements auch für INSERT- und DELETE-Statements.

Zum SeitenanfangZum Seitenanfang

<sql:param>

AttributPflichtfeldBedeutung
valueneinDer gewünschte Wert für den Parameter


Die <sql:update>- und <sql:insert>-Tags können wie PreparedStatements Parameter annehmen. Dabei werden diese in der Reihenfolge in das SQL-Statement eingesetzt, in dem sie innerhalb des betreffenden Update- oder Insert-Tags vorkommen. Der gewünschte Wert kann entweder im "value"-Attribut oder im Body des Tags angegeben werden.

Zum SeitenanfangZum Seitenanfang

<sql:dateParam>

AttributPflichtfeldBedeutung
valuejaDer gewünschte Wert für den Parameter
typeneinDer Typ des Attributs. Kann "date", "time" oder "timestamp" sein


Mit dem <sql:param>-Tag kann man dem Statement bspw. Zahlen oder String-Parameter hinzufügen. Für Datumswerte muss hingegen dieser Tag verwendet werden. Der Wert des Parameter muss – im Unterschied zum <sql:param>-Tag – zwingend im "value"-Attribut angegeben werden.

Zum SeitenanfangZum Seitenanfang

<sql:setDataSource>

AttributPflichtfeldBedeutung
varneinDer Name, unter dem die Datasource-Variable abgelegt werden soll. Wird dieser nicht angegeben, wird die Datenquelle unter dem Namen "javax.servlet.jsp.jstl.sql.dataSource" abgelegt
scopeneinDer gewünschte Gültigkeitsbereich für die unter dem Attribut "var" angegebene DataSource
dataSourceneinGibt die DataSource an, die verwendet werden soll. Dies muss entweder eine Variable vom Typ Datasource sein oder ein String, der einen JNDI-Pfad oder die JDBC-DriverManager-Parameter enthält.
driverneinDer Name des zu verwendenden JDBC-Drivers
urlneinDie URL, unter der die DB erreichbar ist
userneinDer Loginname, der für die DB-Zugriffe verwendet wird
passwordneinDas passende Passwort zum verwendeten Loginnamen


Mit diesem Tag wird konfiguriert, gegen welche Datenbank und mit welchem Login die Anfragen gehen sollen. Lediglich das Attribut "dataSource" der folgenden Tabelle ist nicht selbsterklärend, weswegen wir dieses kurz erläutern. Zunächst einmal kann dieses Attribut ein Objekt vom Typ javax.sql.DataSource entgegen nehmen. Alternativ kann man einen String angeben. Dieser kann entweder ein relativer Pfad auf eine JNDI-Ressource sein oder eine kompakte Form der anderen Driver-spezifischen Attribute dieses Tags. So kann man bspw. eine PostgreSQL-Datenbank mittels des folgenden Strings als Wert des Attributs "dataSource" einbinden: jdbc:postgresql://localhost/databaseName,org.postgresql.Driver,databaseUser,databasePassword. Generell ist der Aufbau wie folgt: URL[,Treiberklasse][,DBLogin][,DB-Passwort]. D.h. lediglich die URL ist ein Pflichtfeld. alle weiteren Attribute sind je nach DB-Typ und -Konfiguration zu ergänzen.
Nutzt man den gerade beschriebenen DataSource-String oder die JDBC-relevanten Parameter, so wird ein java.sql.DriverManager-Objekt erzeugt, das keinerlei Connection-Pooling-Fähigkeiten mitbringt. Die JSTL-Spezifikation warnt daher ausdrücklich vor dieser Verwendungsart - außer für den Fall des Prototypings. Bei produktiven Anwendungen sollte immer mittels des JNDI-Pfads auf eine im Container konfigurierte DataSource zugegriffen werden. Eine solche kann man auch in reinen Servlet-Containern wie Tomcat oder Jetty konfigurieren, ein vollständiger Applikationsserver ist dazu nicht unbedingt erforderlich.

Zum SeitenanfangZum Seitenanfang

Ein Beispiel für die Nutzung

Das folgende Beispiel zeigt eine mögliche Nutzung der SQL-Tags im Zusammenspiel:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
<%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>JSTL-SQL - Example</title>
   </head>
   <body>
      
      <sql:setDataSource driver="org.hsqldb.jdbcDriver" 
                         url="jdbc:hsqldb:file:/var/hsqldb/example_db"
                         user="sa" 
                         password="" 
                         var="exampleDS" 
                         scope="request" />
      
      <sql:query dataSource="${exampleDS}" 
                 var="javax_servlet_jsp_jstl_sql_Result" 
                 maxRows="10" 
                 startRow="0"
                 sql="SELECT * FROM task WHERE ID > ?">
         <sql:param value="1" />
      </sql:query>
      
      <table cellspacing="0" cellpadding="0" style="border-collapse: collapse;">
         <tr>            
            <c:forEach items="${javax_servlet_jsp_jstl_sql_Result.columnNames}" var="column">
               <th style="border: 1px solid #000000; padding: 5px;">${column}</th>
            </c:forEach>
         </tr>
         <c:forEach items="${javax_servlet_jsp_jstl_sql_Result.rows}" var="currRow">
            <tr>
               <c:forEach items="${javax_servlet_jsp_jstl_sql_Result.columnNames}" var="column">
                  <td style="border: 1px solid #000000; padding: 5px;">${currRow[column]}</td>
               </c:forEach>
            </tr>
         </c:forEach>
      </table>
      
   </body>
</html>

Zum SeitenanfangZum Seitenanfang


www.jsptutorial.org
© 2005, 2006, 2007