20. Application web MVC dans une architecture 3tier – Exemple 6, SQL Server Express
20.1. La base de données SQL Server Express
Dans cette version, nous allons installer la liste des personnes dans une table de base de données SQL Server Express 2005 disponible à l'url [http://msdn.microsoft.com/vstudio/express/sql/]. Dans ce qui suit, les copies d’écran proviennent du client EMS Manager Lite pour SQL Server Express [http://www.sqlmanager.net/fr/products/mssql/manager], un client d’administration gratuit du SGBD SQL Server Express.
La base de données s’appelle [dbpersonnes]. Elle contient une table [PERSONNES] :

La table [PERSONNES] contiendra la liste des personnes gérée par l’application web. Elle a été construite avec les ordres SQL suivants :
- ligne 2 : la clé primaire [ID] est de type entier. L'attribut IDENTITY indique que si on insère une ligne sans valeur pour la colonne ID de la table, SQL Express générera lui-même un nombre entier pour cette colonne. Dans IDENTITY(1, 1), le premier paramètre est la première valeur possible pour la clé primaire, le second, l'incrément utilisé dans la génération des nombres.
La table [PERSONNES] pourrait avoir le contenu suivant :

Nous savons que lors de l'insertion d'un objet [Personne] par notre couche [dao], le champ [id] de cet objet est égal à -1 avant l'insertion et a une valeur différente de -1 ensuite, cette valeur étant la clé primaire affectée à la nouvelle ligne insérée dans la table [PERSONNES]. Voyons sur un exemple comment nous allons pouvoir connaître cette valeur.
![]() |
![]() |
L’ordre SQL
permet de connaître la dernière valeur insérée dans le champ ID de la table. Elle est à émettre après l'insertion. C'est une différence avec les SGBD [Firebird] et [Postgres] où on demandait la valeur de la clé primaire de la personne ajoutée avant l'insertion, mais c'est analogue à la génération de clé primaire du SGBD MySQL. Nous l’utiliserons dans le fichier [personnes-sqlexpress.xml] qui rassemble les ordres SQL émis sur la base de données.
20.2. Le projet Eclipse des couches [dao] et [service]
Pour développer les couches [dao] et [service] de notre application avec la base de données[SQL Server Express], nous utiliserons le projet Eclipse [mvc-personnes-06] suivant :

Le projet est un simple projet Java, pas un projet web Tomcat.
Dossier [src]
Ce dossier contient les codes source des couches [dao] et [service] :

Tous les fichiers ayant [sqlexpress] dans leur nom ont pu subir ou non une modification vis à vis des versions Firebird, Postgres et MySQL. Dans ce qui suit, nous ne décrivons que ceux qui ont été modifiés.
Dossier [database]
Ce dossier contient le script de création de la base de données SQL Express des personnes :

Dossier [lib]
Ce dossier contient les archives nécessaires à l’application :
![]() |
On notera la présence du pilote jdbc [sqljdbc.jar] du SGBD [Sql Server Express]. Toutes ces archives font partie du Classpath du projet Eclipse.
20.3. La couche [dao]
La couche [dao] est la suivante :

Nous ne présentons que ce qui change vis à vis de la version [Firebird].
Le fichier de mapping [personne-sqlexpress.xml] est le suivant :
<?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 classe [Personne] -->
<typeAlias alias="Personne.classe"
type="istia.st.mvc.personnes.entites.Personne"/>
<!-- mapping table [PERSONNES] - objet [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 de toutes les personnes -->
<select id="Personne.getAll" resultMap="Personne.map" > select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES</select>
<!-- obtenir une personne en particulier -->
<select id="Personne.getOne" resultMap="Personne.map" >select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES WHERE ID=#value#</select>
<!-- ajouter une personne -->
<insert id="Personne.insertOne" parameterClass="Personne.classe">
insert into
PERSONNES(VERSION, NOM, PRENOM, DATENAISSANCE, MARIE, NBENFANTS)
VALUES(#version#, #nom#, #prenom#, #dateNaissance#, #marie#,
#nbEnfants#)
<selectKey keyProperty="id">
select @@IDENTITY as value
</selectKey>
</insert>
<!-- mettre à jour une personne -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
PERSONNES set VERSION=#version#+1, NOM=#nom#, PRENOM=#prenom#, DATENAISSANCE=#dateNaissance#,
MARIE=#marie#, NBENFANTS=#nbEnfants# WHERE ID=#id# and
VERSION=#version#</update>
<!-- supprimer une personne -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM PERSONNES WHERE
ID=#value# </delete>
<!-- obtenir la valeur de la clé primaire [id] de la dernière personne insérée -->
<select id="Personne.getNextId" resultClass="int">select
LAST_INSERT_ID()</select>
</sqlMap>
C’est le même contenu que [personnes-firebird.xml] aux détails près suivants :
- l’ordre SQL " Personne.insertOne " a changé lignes 29-37 :
- l'ordre SQL d'insertion est exécuté avant l'ordre SELECT qui va permettre de récupérer la valeur de la clé primaire de la ligne insérée
- l'ordre SQL d'insertion n'a pas de valeur pour la colonne ID de la table [PERSONNES]
Cela reflète l'exemple d'insertion que nous avons commenté paragraphe 20.1. A noter, qu'on retrouve ici le problème d'insertions simultanées par des threads différents décrit pour MySQL au paragraphe 19.3.
La classe d’implémentation [DaoImplCommon] de la couche [dao] est celle des trois versions précédentes.
La configuration de la couche [dao] a été adaptée au SGBD [SQL Express]. Ainsi, le fichier de configuration [spring-config-test-dao-sqlexpress.xml] est-il le suivant :
<?xml version="1.0" encoding="ISO_8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- la source de donnéees 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>
<!-- la classes d'accè à la couche [dao] -->
<bean id="dao" class="istia.st.mvc.personnes.dao.DaoImplCommon">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
</beans>
- lignes 5-19 : le bean [dataSource] désigne maintenant la base [SQL Express] [dbpersonnes] dont l’administrateur est [sa] avec le mot de passe [msde]. Le lecteur modifiera cette configuration selon son propre environnement.
- ligne 31 : la classe [DaoImplCommon] est la classe d'implémentation de la couche [dao]
La ligne 11 mérite des explications :
<value>jdbc:sqlserver://localhost\\SQLEXPRESS:4000;databaseName=dbpersonnes</value>
- //localhost : indique que le serveur SQL Express est sur la même machine que notre application Java
- \\SQLEXPRESS : est le nom d'une instance de SQL Server. Il semble que plusieurs instances peuvent s'exécuter en même temps. Il semble donc logique de nommer l'instance à laquelle on s'adresse. Ce nom peut être obtenu grâce [SQL Server Configuration Manager] installé normalement en même temps que SQL Express :


- 4000 : port d'écoute de SQL Express. Cela est dépendant de la configuration du serveur. Par défaut, il travaille avec des ports dynamiques, donc pas connus à l'avance. On ne précise alors pas de port dans l'url JDBC. Ici, nous avons travaillé avec un port fixe, le port 4000. Cela s'obtient par configuration :
![]() |
- l'attribut dataBaseName fixe la base de données avec laquelle on veut travailler. C'est celle qui a été créée avec le client EMS :

Ces modifications faites, on peut passer aux tests.
20.4. Les tests des couches [dao] et [service]
Les tests des couches [dao] et [service] sont les mêmes que pour la version [Firebird]. Les résultats obtenus sont les suivants :
![]() |
On constate que les tests ont été passés avec succès avec l'implémentation [DaoImplCommon]. Nous n'aurons pas à dériver cette classe comme il avait été nécessaire de le faire avec le SGBD [Firebird].
20.5. Tests de l’application [web]
Pour tester l’application web avec le SGBD [SQL Server Express], nous construisons un projet Eclipse [mvc-personnes-06B] de façon analogue à celle utilisée pour construire les projets web précédents.
Nous déployons le projet web [mvc-personnes-05B] au sein de Tomcat :
![]() | ![]() |
Le SGBD SQL server Express est lancé. Le contenu de la table [PERSONNES] est alors le suivant :

Tomcat est lancé à son tour. Avec un navigateur, nous demandons l’url [http://localhost:8080/mvc-personnes-06B] :

Nous ajoutons une nouvelle personne avec le lien [Ajout] :
![]() | ![]() |
Nous vérifions l’ajout dans la base de données :

Le lecteur est invité à faire d’autres tests [modification, suppression].








