18. Aplicação Web MVC numa arquitetura de 3 camadas – Exemplo 4, Postgres
18.1. A base de dados Postgres
Nesta versão, iremos armazenar a lista de pessoas numa tabela da base de dados Postgres 8.x [http://www.postgres.org]. A seguir, as capturas de ecrã foram tiradas do cliente EMS PostgreSQL Manager Lite [http://www.sqlmanager.net/fr/products/postgresql/manager], um cliente de administração gratuito para o SGBD Postgres.
A base de dados chama-se [dbpersonnes]. Contém uma tabela chamada [PERSONNES]:

A tabela [PERSONNES] conterá a lista de pessoas geridas pela aplicação web. Foi criada utilizando as seguintes instruções SQL:
Não nos deteremos nesta tabela, que é análoga à tabela [PERSONNES] do Firebird discutida anteriormente. Note-se, no entanto, que os nomes das colunas e da tabela estão entre aspas. Além disso, estes nomes distinguem maiúsculas de minúsculas. É possível que este comportamento no Postgres 8.x seja configurável. Não investiguei isto mais a fundo.
A tabela [PERSONNES] poderia ter o seguinte conteúdo:

Para além da tabela [PERSONNES], a base de dados [dbpersonnes] possui um objeto chamado sequência, denominado [SEQ_ID]. Este gerador produz números inteiros sucessivos que utilizaremos para preencher a chave primária [ID] da classe [PERSONNES]. Vejamos um exemplo para ilustrar como funciona:
![]() |
![]() |
Podemos ver que o [Próximo valor] da sequência [SEQ_ID] mudou (clique duas vezes nele + F5 para atualizar):
![]() |
A instrução SQL
permite-nos, portanto, recuperar o valor seguinte na sequência [SEQ_ID]. Iremos utilizá-la no ficheiro [people-postgres.xml], que contém as instruções SQL executadas no SGBD.
18.2. O projeto Eclipse para as camadas [dao] e [service]
Para desenvolver as camadas [dao] e [service] da nossa aplicação com a base de dados Postgres 8.x, utilizaremos o seguinte projeto Eclipse [spring-mvc-39]:

O projeto é um projeto Java simples, não um projeto web Tomcat.
Pasta [src]
Esta pasta contém o código-fonte das camadas [dao] e [service]:

Todos os ficheiros com [postgres] no nome podem ou não ter sido modificados em comparação com a versão Firebird. Abaixo, descrevemos os ficheiros modificados.
Pasta [database]
Esta pasta contém o script para criar a base de dados Postgres para os utilizadores:
![]()
pasta [lib]
Esta pasta contém os arquivos necessários para o funcionamento da aplicação:
![]() |
Note a presença do controlador JDBC do SGBD Postgres 8.x. Todos estes ficheiros fazem parte do classpath do projeto Eclipse.
18.3. A camada [dao]
A camada [dao] é a seguinte:

Apresentamos apenas as alterações em relação à versão [Firebird].
O ficheiro de mapeamento [personne-postgres.xml] é o seguinte:
<?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">
<!-- warning - Postgresql 8 requires exact spelling of column names
et des tables ainsi que des guillemets autour de ces noms -->
<sqlMap>
<!-- alias class [Person] -->
<typeAlias alias="Personne.classe"
type="istia.st.mvc.personnes.entites.Personne"/>
<!-- mapping table [PERSONNES] - object [Person] -->
<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>
<!-- list of all persons -->
<select id="Personne.getAll" resultMap="Personne.map" > select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES"</select>
<!-- get a specific person -->
<select id="Personne.getOne" resultMap="Personne.map" >select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES" WHERE "ID"=#value#</select>
<!-- add a person -->
<insert id="Personne.insertOne" parameterClass="Personne.classe">
<selectKey keyProperty="id">
SELECT nextval('"SEQ_ID"') as value
</selectKey>
insert into "PERSONNES"("ID", "VERSION",
"NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS") VALUES(#id#,
#version#, #nom#, #prenom#, #dateNaissance#, #marie#, #nbEnfants#)
</insert>
<!-- update a person -->
<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>
<!-- delete a person -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM
"PERSONNES" WHERE "ID"=#value# </delete>
</sqlMap>
Este é o mesmo conteúdo que [people-firebird.xml], com as seguintes pequenas diferenças:
- os nomes das colunas e das tabelas estão entre aspas e distinguem maiúsculas de minúsculas
- A instrução SQL «Person.insertOne» foi alterada nas linhas 34–41. A forma como a chave primária é gerada no Postgres difere da utilizada no Firebird:
- linha 36: a instrução SQL [SELECT nextval('"SEQ_ID"')] fornece a chave primária. A sintaxe [as value] é obrigatória. [value] representa a chave obtida. Este valor será atribuído ao campo do objeto [Person] designado pelo atributo [keyProperty] (linha 35), neste caso o campo [id].
- As instruções SQL dentro da tag <insert> são executadas na ordem em que aparecem. Portanto, a instrução SELECT é executada antes da INSERT. Quando a operação de inserção ocorrer, o campo [id] do objeto [Person] já terá sido atualizado pela instrução SQL SELECT.
- Linhas 38–40: inserção do objeto [Person]
A classe de implementação [DaoImplCommon] da camada [dao] é a que é estudada na versão [Firebird].
A configuração da camada [dao] foi adaptada ao SGBD [Postgres]. Assim, o ficheiro de configuração [spring-config-test-dao-postgres.xml] é o seguinte:
<?xml version="1.0" encoding="ISO_8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- data source DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql:dbpersonnes</value>
</property>
<property name="username">
<value>postgres</value>
</property>
<property name="password">
<value>postgres</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-postgres.xml</value>
</property>
</bean>
<!-- the [dao] layer access classes -->
<bean id="dao" class="istia.st.mvc.personnes.dao.DaoImplCommon">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
</beans>
- linhas 5–19: O bean [dataSource] refere-se agora à base de dados [Postgres] [dbpersonnes], cujo administrador é [postgres] com a palavra-passe [postgres]. O leitor deve modificar esta configuração de acordo com o seu próprio ambiente.
- linha 31: a classe [DaoImplCommon] é a classe de implementação para a camada [dao]
Com estas alterações feitas, podemos passar aos testes.
18.4. Testes para as camadas [dao] e [service]
Os testes para as camadas [dao] e [service] são os mesmos da versão [Firebird]. Vamos iniciar o SGBD Postgres e, em seguida, executar os testes do Eclipse. Os resultados obtidos são os seguintes:
![]() |
Podemos ver que os testes foram bem-sucedidos com a implementação [DaoImplCommon]. Não precisaremos derivar esta classe, como tivemos de fazer com o SGBD [Firebird].
18.5. Testes da aplicação [Web]
Para testar a aplicação web com o SGBD [Postgres], criamos um projeto Eclipse [mvc-personnes-04B] de forma análoga à utilizada para criar o projeto [mvc-personnes-03B] com a base de dados Firebird (ver Secção 17.7). No entanto, não precisamos de recriar os arquivos [personnes-dao.jar] e [personnes-service.jar]. Na verdade, não modificámos nenhuma classe em comparação com o projeto [mvc-personnes-03B]. O arquivo [personnes-dao.jar] contém simplesmente a classe [DaoImplFirebird], que já não é necessária.

Implementamos o projeto web [mvc-personnes-04B] no Tomcat:
![]() | ![]() |
Estamos prontos para os testes s. O conteúdo da tabela [PERSONNES] é agora o seguinte:

O Tomcat está a funcionar. Utilizando um navegador, solicitamos o URL [http://localhost:8080/mvc-personnes-04B]:

Adicionamos uma nova pessoa através do link [Adicionar]:
![]() | ![]() |
Verificamos a adição na base de dados:

O leitor é convidado a realizar mais testes [atualizar, eliminar].








