20. Webanwendung MVC in einer 3-Tier-Architektur – Beispiel 6, SQL Server Express
20.1. Die Datenbank SQL Server Express
In dieser Version werden wir die Personenliste in einer Datenbanktabelle von SQL Server Express 2005 speichern, die unter der URL [http://msdn.microsoft.com/vstudio/express/sql/] verfügbar ist. Die folgenden Screenshots stammen aus dem Client EMS Manager Lite für SQL Server Express [http://www.sqlmanager.net/fr/products/mssql/manager], einem kostenlosen Verwaltungsprogramm für den SGBD SQL Server Express.
Die Datenbank heißt [dbpersonnes]. Sie enthält eine Tabelle [PERSONNES]:

Die Tabelle [PERSONNES] enthält die Liste der von der Webanwendung verwalteten Personen. Sie wurde mit den folgenden Befehlen SQL erstellt:
- Zeile 2: Der Primärschlüssel [ID] ist vom Typ Ganzzahl. Das Attribut IDENTITY gibt an, dass SQL Express bei Einfügen einer Zeile ohne Wert für die Spalte ID der Tabelle selbst eine Ganzzahl für diese Spalte generiert. In IDENTITY(1, 1) ist der erste Parameter der erste mögliche Wert für den Primärschlüssel, der zweite das bei der Nummerngenerierung verwendete Inkrement.
Die Tabelle [PERSONNES] könnte folgenden Inhalt haben:

Wir wissen, dass beim Einfügen eines Objekts [Personne] durch unsere Schicht [dao] das Feld [id] dieses Objekts vor dem Einfügen den Wert -1 hat und danach einen anderen Wert als -1 annimmt, wobei dieser Wert der Primärschlüssel ist, der der neuen, in die Tabelle [PERSONNES] eingefügten Zeile zugewiesen wurde. Schauen wir uns anhand eines Beispiels an, wie wir diesen Wert ermitteln können.
![]() |
![]() |
Der Auftrag SQL
ermöglicht es, den zuletzt in das Feld ID der Tabelle eingefügten Wert zu ermitteln. Sie ist nach dem Einfügen auszuführen. Dies unterscheidet sich von den Befehlen SGBD, [Firebird] und [Postgres], bei denen der Wert des Primärschlüssels der hinzugefügten Person vor dem Einfügen abgefragt wurde, dies entspricht jedoch der Primärschlüsselgenerierung bei den Befehlen SGBD und MySQL. Wir werden ihn in der Datei [personnes-sqlexpress.xml] verwenden, die die an die Datenbank gesendeten Befehle SQL zusammenfasst.
20.2. Das Eclipse-Projekt der Schichten [dao] und [service]
Um die Schichten [dao] und [service] unserer Anwendung mit der Datenbank [SQL Server Express] zu entwickeln, verwenden wir das folgende Eclipse-Projekt [mvc-personnes-06]:

Das Projekt ist ein einfaches Java-Projekt, kein Tomcat-Webprojekt.
Ordner [src]
Dieser Ordner enthält den Quellcode der Schichten [dao] und [service]:

Alle Dateien, deren Name „[sqlexpress]“ enthält, wurden möglicherweise gegenüber den Versionen für Firebird, Postgres und MySQL geändert – oder auch nicht. Im Folgenden werden nur die Dateien beschrieben, die geändert wurden.
Ordner [database]
Dieser Ordner enthält das Skript zur Erstellung der SQL Express-Datenbank für Personen:
![]()
Ordner [lib]
Dieser Ordner enthält die für die Anwendung erforderlichen Archive:
![]() |
Zu beachten ist das Vorhandensein des JDBC-Treibers [sqljdbc.jar] sowie der Dateien SGBD und [Sql Server Express]. Alle diese Archive sind Teil des Eclipse-Projekts Classpath.
20.3. Die Schicht [dao]
Die Ebene [dao] sieht wie folgt aus:

Wir stellen hier nur die Änderungen gegenüber der Version [Firebird] vor.
Die Mapping-Datei [personne-sqlexpress.xml] lautet wie folgt:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap>
<!-- Alias der Klasse [Personne] -->
<typeAlias alias="Personne.classe"
type="istia.st.mvc.personnes.entites.Personne"/>
<!-- Zuordnungstabelle [PERSONNES] – Objekt [Personne] -->
<resultMap id="Personne.map"
class="istia.st.mvc.personnes.entites.Personne">
<result property="id" column="ID" />
<result property="version" column="VERSION" />
<result property="nom" column="NOM"/>
<result property="prenom" column="PRENOM"/>
<result property="dateNaissance" column="DATENAISSANCE"/>
<result property="marie" column="MARIE"/>
<result property="nbEnfants" column="NBENFANTS"/>
</resultMap>
<!-- Liste aller Personen -->
<select id="Personne.getAll" resultMap="Personne.map" > select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES</select>
<!-- eine bestimmte Person abrufen -->
<select id="Personne.getOne" resultMap="Personne.map" >select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES WHERE ID=#Wert#</select>
<!-- eine Person hinzufügen -->
<insert id="Personne.insertOne" parameterClass="Personne.classe">
insert into
PERSONNES(VERSION, NOM, PRENOM, DATENAISSANCE, MARIE, NBENFANTS)
VALUES(#Version#, #Nachname#, #Vorname#, #dateNaissance#, #verheiratet#,
#nbEnfants#)
<selectKey keyProperty="id">
select @@IDENTITY as value
</selectKey>
</insert>
<!-- eine Person aktualisieren -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
PERSONNES set VERSION=#Version#+1, NOM=#Nachname#, PRENOM=#Vorname#, DATENAISSANCE=#dateNaissance#,
MARIE=#Ehepartner#, NBENFANTS=#nbEnfants# WHERE ID=#id# und
VERSION=#Version#</update>
<!-- eine Person löschen -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM PERSONNES WHERE
ID=#Wert# </delete>
<!-- den Wert des Primärschlüssels [id] der zuletzt eingefügten Person abrufen -->
<select id="Personne.getNextId" resultClass="int">select
LAST_INSERT_ID()</select>
</sqlMap>
Der Inhalt entspricht dem von [personnes-firebird.xml], mit folgenden Abweichungen:
- Der Befehl SQL „Personne.insertOne“ wurde in den Zeilen 29–37 geändert:
- Der Einfügebefehl SQL wird vor dem Befehl SELECT ausgeführt, wodurch der Wert des Primärschlüssels der eingefügten Zeile abgerufen werden kann
- Der Einfügebbefehl SQL enthält keinen Wert für die Spalte ID der Tabelle [PERSONNES]
Dies spiegelt das Einfügebeispiel wider, das wir in Abschnitt 20.1 erläutert haben. Zu beachten ist, dass hier das Problem gleichzeitiger Einfügungen durch verschiedene Threads auftritt, das für MySQL in Abschnitt 19.3 beschrieben wurde.
Die Implementierungsklasse [DaoImplCommon] der Schicht [dao] entspricht der der drei vorherigen Versionen.
Die Konfiguration der Schicht [dao] wurde an SGBD und [SQL Express] angepasst. Somit lautet die Konfigurationsdatei [spring-config-test-dao-sqlexpress.xml] wie folgt:
<?xml version="1.0" encoding="ISO_8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- die Datenquelle DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>com.microsoft.sqlserver.jdbc.SQLServerDriver</value>
</property>
<property name="url">
<value>jdbc:sqlserver://localhost\\SQLEXPRESS:4000;databaseName=dbpersonnes</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value>msde</value>
</property>
</bean>
<!-- SqlMapCllient -->
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="configLocation">
<value>classpath:sql-map-config-sqlexpress.xml</value>
</property>
</bean>
<!-- Zugriffsklassen auf die Ebene [dao] -->
<bean id="dao" class="istia.st.mvc.personnes.dao.DaoImplCommon">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
</beans>
- Zeilen 5–19: Die Bean [dataSource] verweist nun auf die Datenbank [SQL Express] [dbpersonnes], deren Administrator [sa] ist und deren Passwort [msde] lautet. Der Leser sollte diese Konfiguration entsprechend seiner eigenen Umgebung anpassen.
- Zeile 31: Die Klasse [DaoImplCommon] ist die Implementierungsklasse der Schicht [dao]
Zeile 11 bedarf einer Erläuterung:
- //localhost: gibt an, dass sich der SQL Express-Server auf demselben Rechner wie unsere Java-Anwendung befindet
- \\SQLEXPRESS: ist der Name einer Instanz des SQL-Servers. Es scheint, dass mehrere Instanzen gleichzeitig ausgeführt werden können. Es erscheint daher sinnvoll, die Instanz zu benennen, an die man sich wendet. Dieser Name kann über [SQL Server Configuration Manager] ermittelt werden, das normalerweise zusammen mit SQL Express installiert wird:


- 4000: Listening-Port von SQL Express. Dies hängt von der Serverkonfiguration ab. Standardmäßig arbeitet das Programm mit dynamischen Ports, die daher nicht im Voraus bekannt sind. Daher wird in der URL JDBC kein Port angegeben. Hier haben wir mit einem festen Port gearbeitet, nämlich Port 4000. Dies wird über die Konfiguration erreicht:
![]() |
- Das Attribut dataBaseName legt die Datenbank fest, mit der gearbeitet werden soll. Es handelt sich um die Datenbank, die mit dem Client EMS erstellt wurde:

Nachdem diese Änderungen vorgenommen wurden, kann mit den Tests begonnen werden.
20.4. Tests der Schichten [dao] und [service]
Die Tests der Schichten [dao] und [service] entsprechen denen der Version [Firebird]. Die erzielten Ergebnisse lauten wie folgt:
![]() |
Es ist festzustellen, dass die Tests mit der Implementierung [DaoImplCommon] erfolgreich bestanden wurden. Wir müssen diese Klasse nicht ableiten, wie es bei den Versionen SGBD und [Firebird] erforderlich war.
20.5. Tests der Anwendung [web]
Um die Webanwendung mit den Implementierungen SGBD und [SQL Server Express] zu testen, erstellen wir ein Eclipse-Projekt [mvc-personnes-06B] analog zu den zuvor erstellten Webprojekten.
Wir stellen das Webprojekt [mvc-personnes-05B] in Tomcat bereit:
![]() | ![]() |
Der Express-Server SGBD SQL wird gestartet. Der Inhalt der Tabelle [PERSONNES] sieht dann wie folgt aus:

Anschließend wird Tomcat gestartet. Mit einem Browser rufen wir die URL [http://localhost:8080/mvc-personnes-06B] auf:

Wir fügen eine neue Person über den Link [Ajout] hinzu:
![]() | ![]() |
Wir überprüfen den Eintrag in der Datenbank:

Der Leser wird gebeten, weitere Tests durchzuführen: [modification, suppression].








