20. Applicazione web MVC in un’architettura a 3 livelli – Esempio 6, SQL Server Express
20.1. Il database SQL Server Express
In questa versione, installeremo l'elenco delle persone in una tabella del database SQL Server Express 2005 disponibile all'URL [http://msdn.microsoft.com/vstudio/express/sql/]. Di seguito, le schermate provengono dal client EMS Manager Lite per SQL Server Express [http://www.sqlmanager.net/fr/products/mssql/manager], un client di amministrazione gratuito di SGBD SQL Server Express.
Il database si chiama [dbpersonnes]. Contiene una tabella [PERSONNES]:

La tabella [PERSONNES] conterrà l’elenco delle persone gestite dall’applicazione web. È stata creata con i seguenti comandi SQL:
- riga 2: la chiave primaria [ID] è di tipo intero. L'attributo IDENTITY indica che, se si inserisce una riga senza valore per la colonna ID della tabella, SQL Express genererà automaticamente un numero intero per quella colonna. In IDENTITY(1, 1), il primo parametro è il primo valore possibile per la chiave primaria, il secondo è l'incremento utilizzato nella generazione dei numeri.
La tabella [PERSONNES] potrebbe avere il seguente contenuto:

Sappiamo che durante l’inserimento di un oggetto [Personne] da parte del nostro livello [dao], il campo [id] di tale oggetto è pari a -1 prima dell’inserimento e assume un valore diverso da -1 in seguito; tale valore corrisponde alla chiave primaria assegnata alla nuova riga inserita nella tabella [PERSONNES]. Vediamo con un esempio come possiamo determinare questo valore.
![]() |
![]() |
L’ordine SQL
consente di conoscere l’ultimo valore inserito nel campo ID della tabella. Deve essere emesso dopo l’inserimento. Si tratta di una differenza rispetto ai comandi SGBD, [Firebird] e [Postgres], in cui si richiedeva il valore della chiave primaria della persona aggiunta prima dell’inserimento, ma è analogo alla generazione della chiave primaria dei file SGBD e MySQL. Lo useremo nel file [personnes-sqlexpress.xml] che raccoglie i comandi SQL emessi sul database.
20.2. Il progetto Eclipse dei livelli [dao] e [service]
Per sviluppare i livelli [dao] e [service] della nostra applicazione con il database [SQL Server Express], utilizzeremo il seguente progetto Eclipse [mvc-personnes-06]:

Il progetto è un semplice progetto Java, non un progetto web Tomcat.
Cartella [src]
Questa cartella contiene i codici sorgente dei livelli [dao] e [service]:

Tutti i file che contengono [sqlexpress] nel nome potrebbero aver subito o meno una modifica rispetto alle versioni Firebird, Postgres e MySQL. Di seguito descriviamo solo quelli che sono stati modificati.
Cartella [database]
Questa cartella contiene lo script per la creazione del database SQL Express delle persone:
![]()
Cartella [lib]
Questa cartella contiene gli archivi necessari all’applicazione:
![]() |
Da notare la presenza del driver JDBC [sqljdbc.jar], SGBD e [Sql Server Express]. Tutti questi file fanno parte del Classpath del progetto Eclipse.
20.3. Il livello [dao]
Il livello [dao] è il seguente:

Presentiamo solo le modifiche rispetto alla versione [Firebird].
Il file di mappatura [personne-sqlexpress.xml] è il seguente:
<?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"/>
<!-- tabella di mappatura [PERSONNES] - oggetto [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>
<!-- elenco di tutte le persone -->
<select id="Personne.getAll" resultMap="Personne.map" > select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES</select>
<!-- recupera una persona specifica -->
<select id="Personne.getOne" resultMap="Personne.map" >select ID, VERSION, NOM,
PRENOM, DATENAISSANCE, MARIE, NBENFANTS FROM PERSONNES WHERE ID=#valore#</select>
<!-- aggiungere una persona -->
<insert id="Personne.insertOne" parameterClass="Personne.classe">
insert into
PERSONNES(VERSION, NOM, PRENOM, DATENAISSANCE, MARIE, NBENFANTS)
VALUES(#versione#, #cognome#, #nome#, #dateNaissance#, #maria#,
#nbEnfants#)
<selectKey keyProperty="id">
select @@IDENTITY as value
</selectKey>
</insert>
<!-- aggiornare una persona -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
PERSONNES set VERSION=#versione#+1, NOM=#cognome#, PRENOM=#nome#, DATENAISSANCE=#dateNaissance#,
MARIE=#marie#, NBENFANTS=#nbEnfants# WHERE ID=#id# e
VERSION=#versione#</aggiornamento>
<!-- eliminare una persona -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM PERSONNES WHERE
ID=#valore# </delete>
<!-- ottenere il valore della chiave primaria [id] dell'ultima persona inserita -->
<select id="Personne.getNextId" resultClass="int">select
LAST_INSERT_ID()</select>
</sqlMap>
Il contenuto è identico a quello di [personnes-firebird.xml], salvo le seguenti piccole differenze:
- l'ordine SQL " Personne.insertOne " è stato modificato alle righe 29-37:
- il comando di inserimento SQL viene eseguito prima del comando SELECT, che consentirà di recuperare il valore della chiave primaria della riga inserita
- il comando di inserimento SQL non ha alcun valore per la colonna ID della tabella [PERSONNES]
Ciò rispecchia l’esempio di inserimento che abbiamo commentato al paragrafo 20.1. Da notare che qui si riscontra il problema degli inserimenti simultanei da parte di thread diversi descritto per MySQL al paragrafo 19.3.
La classe di implementazione [DaoImplCommon] del livello [dao] è quella delle tre versioni precedenti.
La configurazione del livello [dao] è stata adattata a SGBD e [SQL Express]. Pertanto, il file di configurazione [spring-config-test-dao-sqlexpress.xml] è il seguente:
<?xml version="1.0" encoding="ISO_8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- la fonte dei dati 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>
<!-- le classi di accesso al livello [dao] -->
<bean id="dao" class="istia.st.mvc.personnes.dao.DaoImplCommon">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
</beans>
- righe 5-19: il bean [dataSource] ora fa riferimento al database [SQL Express] [dbpersonnes], il cui amministratore è [sa] con la password [msde]. Il lettore dovrà modificare questa configurazione in base al proprio ambiente.
- riga 31: la classe [DaoImplCommon] è la classe di implementazione del livello [dao]
La riga 11 merita alcune spiegazioni:
- //localhost: indica che il server SQL Express si trova sulla stessa macchina della nostra applicazione Java
- \\SQLEXPRESS: è il nome di un'istanza di SQL Server. Sembra che possano essere eseguite più istanze contemporaneamente. Sembra quindi logico specificare il nome dell’istanza a cui ci si rivolge. Questo nome può essere ottenuto tramite [SQL Server Configuration Manager], che di norma viene installato insieme a SQL Express:


- 4000: porta di ascolto di SQL Express. Questo dipende dalla configurazione del server. Per impostazione predefinita, il programma utilizza porte dinamiche, quindi non note in anticipo. Non si specifica quindi alcuna porta nell'URL JDBC. In questo caso, abbiamo utilizzato una porta fissa, la porta 4000. Ciò si ottiene tramite la seguente configurazione:
![]() |
- L'attributo dataBaseName specifica il database con cui si desidera lavorare. Si tratta di quello creato con il client EMS:

Una volta apportate queste modifiche, si può procedere ai test.
20.4. Test dei livelli [dao] e [service]
I test dei livelli [dao] e [service] sono gli stessi della versione [Firebird]. I risultati ottenuti sono i seguenti:
![]() |
Si constata che i test sono stati superati con successo con l’implementazione [DaoImplCommon]. Non sarà necessario derivare questa classe, come invece era stato necessario fare con SGBD e [Firebird].
20.5. Test dell’applicazione [web]
Per testare l’applicazione web con SGBD e [SQL Server Express], creiamo un progetto Eclipse [mvc-personnes-06B] in modo analogo a quello utilizzato per creare i precedenti progetti web.
Distribuiamo il progetto web [mvc-personnes-05B] all’interno di Tomcat:
![]() | ![]() |
Viene avviato il server Express SGBD SQL. Il contenuto della tabella [PERSONNES] è quindi il seguente:

A sua volta viene avviato Tomcat. Tramite un browser, richiediamo l’URL [http://localhost:8080/mvc-personnes-06B]:

Aggiungiamo una nuova persona tramite il link [Ajout]:
![]() | ![]() |
Verifichiamo l’aggiunta nel database:

Il lettore è invitato a effettuare ulteriori test con il codice [modification, suppression].








