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

A tabela [PERSONNES] conterá a lista de pessoas geridas pela aplicação web. Foi criada com os seguintes comandos SQL:
Não nos detemos nesta tabela, que é análoga à tabela [PERSONNES] do tipo Firebird analisada anteriormente. Note-se, no entanto, que os nomes das colunas e das tabelas estão entre aspas. Além disso, estes nomes distinguem maiúsculas de minúsculas. É possível que este modo de funcionamento do Postgres 8.x seja configurável. Não aprofundei esta questão.
A tabela [PERSONNES] poderia ter o seguinte conteúdo:

Para além da tabela [PERSONNES], a base de dados [dbpersonnes] possui um objeto denominado «sequência» e com o nome [SEQ_ID]. Este gerador produz números inteiros sucessivos que utilizaremos para atribuir um valor à chave primária [ID] da classe [PERSONNES]. Vejamos um exemplo para ilustrar o seu funcionamento:
![]() |
![]() |
Pode-se verificar que o valor [Next value] da sequência [SEQ_ID] mudou (clique duas vezes nele + F5 para atualizar):
![]() |
A ordem SQL
permite, assim, obter o seguinte valor da sequência [SEQ_ID]. Iremos utilizá-lo no ficheiro [personnes-postgres.xml], que reúne as ordens SQL emitidas no SGBD.
18.2. O projeto Eclipse das 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 os códigos-fonte das camadas [dao] e [service]:

Todos os ficheiros cujo nome inclua [postgres] podem ou não ter sofrido alterações em relação à versão Firebird. A seguir, descrevemos os ficheiros alterados.
Pasta [database]
Esta pasta contém o script de criação da base de dados Postgres das pessoas:
![]()
Pasta [lib]
Esta pasta contém os ficheiros necessários para a aplicação:
![]() |
De salientar 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">
<!-- Atenção — o PostgreSQL 8 exige a grafia exata dos nomes das colunas
et des tables ainsi que des guillemets autour de ces noms -->
<sqlMap>
<!-- alias da classe [Personne] -->
<typeAlias alias="Personne.classe"
type="istia.st.mvc.personnes.entites.Personne"/>
<!-- tabela de mapeamento [PERSONNES] - objeto [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>
<!-- lista de todas as pessoas -->
<select id="Personne.getAll" resultMap="Personne.map" > select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES"</select>
<!-- obter uma pessoa específica -->
<select id="Personne.getOne" resultMap="Personne.map" >select "ID",
"VERSION", "NOM", "PRENOM", "DATENAISSANCE", "MARIE", "NBENFANTS" FROM
"PERSONNES" WHERE "ID"=#valor#</select>
<!-- adicionar uma pessoa -->
<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#,
#versão#, #apelido#, #nome próprio#, #dateNaissance#, #casada com#, #nbEnfants#)
</insert>
<!-- atualizar um utilizador -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
"PERSONNES" set "VERSION"=#versão#+1, "NOM"=#apelido#, "PRENOM"=#nome próprio#,
"DATENAISSANCE"=#dateNaissance#, "MARIE"=#marie#, "NBENFANTS"=#nbEnfants#
WHERE "ID"=#id# e "VERSION"=#versão#</update>
<!-- eliminar uma pessoa -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM
"PERSONNES" WHERE "ID"=#valor# </delete>
</sqlMap>
O conteúdo é idêntico ao do ficheiro [personnes-firebird.xml], com as seguintes diferenças:
- os nomes das colunas e das tabelas estão entre aspas e distinguem maiúsculas de minúsculas
- a ordem SQL " Personne.insertOne " foi alterada nas linhas 34-41. A forma de gerar a chave primária com o Postgres é diferente da utilizada com o Firebird:
- linha 36: a ordem 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 [Personne] designado pelo atributo [keyProperty] (linha 35), neste caso o campo [id].
- As ordens SQL da baliza <insert> são executadas pela ordem em que são encontradas. Assim, a ordem SELECT é executada antes da ordem INSERT. No momento da operação de inserção, o campo [id] do objeto [Personne] terá, portanto, sido atualizado pela ordem SQL SELECT.
- linhas 38-40: inserção do objeto [Personne]
A classe de implementação [DaoImplCommon] da camada [dao] é a que foi analisada na versão [Firebird].
A configuração da camada [dao] foi adaptada para SGBD e [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>
<!-- a fonte de dados 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>
<!-- a classe de acesso à camada [dao] -->
<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 deverá adaptar esta configuração ao seu próprio ambiente.
- linha 31: a classe [DaoImplCommon] é a classe de implementação da camada [dao]
Feitas estas alterações, pode-se passar aos testes.
18.4. Testes das camadas [dao] e [service]
Os testes das camadas [dao] e [service] são os mesmos que para a versão [Firebird]. Vamos iniciar o SGBD Postgres e, em seguida, os testes do Eclipse. Os resultados obtidos são os seguintes:
![]() |
Verifica-se que os testes foram concluídos com sucesso com a implementação [DaoImplCommon]. Não será necessário derivar esta classe, como tinha sido necessário fazer com o SGBD e o [Firebird].
18.5. Testes da aplicação [web]
Para testar a aplicação web com o SGBD e o [Postgres], criamos um projeto Eclipse [mvc-personnes-04B] de forma semelhante à utilizada para criar o projeto [mvc-personnes-03B] com a base de dados Firebird (ver parágrafo 17.7). No entanto, não precisamos de recriar os arquivos [personnes-dao.jar] e [personnes-service.jar]. Com efeito, não alterámos nenhuma classe em relação ao projeto [mvc-personnes-03B]. Simplesmente, o arquivo [personnes-dao.jar] contém a classe [DaoImplFirebird], que se tornou desnecessária.

Estamos a implementar o projeto web [mvc-personnes-04B] no Tomcat:
![]() | ![]() |
Estamos prontos para os testes de « ». O conteúdo da tabela [PERSONNES] é, então, o seguinte:

O Tomcat está em execução. Num navegador, acedemos à URL [http://localhost:8080/mvc-personnes-04B]:

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

O leitor é convidado a realizar outros testes com o [modification, suppression].








