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

A tabela [PERSONNES] conterá a lista de pessoas gerenciadas pelo aplicativo web. Ela foi criada com os seguintes comandos SQL:
Não nos deteremos nessa tabela, que é análoga à tabela [PERSONNES] do tipo Firebird analisada anteriormente. Observe-se, no entanto, que os nomes das colunas e das tabelas estão entre aspas. Além disso, esses nomes diferenciam maiúsculas de minúsculas. É possível que esse modo de funcionamento do Postgres 8.x seja configurável. Não aprofundei essa questão.
A tabela [PERSONNES] poderia ter o seguinte conteúdo:

Além da tabela [PERSONNES], o banco de dados [dbpersonnes] possui um objeto chamado sequência, denominado [SEQ_ID]. Esse gerador fornece números inteiros sucessivos que utilizaremos para atribuir um valor à chave primária [ID] da classe [PERSONNES]. Vejamos um exemplo para ilustrar seu funcionamento:
![]() |
![]() |
É possível observar que o valor [Next value] da sequência [SEQ_ID] mudou (clique duas vezes nele + F5 para atualizar):
![]() |
O pedido SQL
permite, portanto, obter o seguinte valor da sequência [SEQ_ID]. Vamos utilizá-lo no arquivo [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] de nossa aplicação com o banco de dados Postgres 8.x, utilizaremos o seguinte projeto Eclipse [spring-mvc-39]:

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

Todos os arquivos que contêm [postgres] no nome podem ou não ter sofrido alterações em relação à versão do Firebird. A seguir, descrevemos os arquivos modificados.
Pasta [database]
Esta pasta contém o script de criação do banco de dados Postgres de pessoas:
![]()
Pasta [lib]
Esta pasta contém os arquivos necessários para o funcionamento do aplicativo:
![]() |
Destaca-se a presença do driver JDBC do SGBD para Postgres 8.x. Todos esses arquivos 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 arquivo 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#, #sobrenome#, #nome#, #dateNaissance#, #casada#, #nbEnfants#)
</insert>
<!-- atualizar um usuário -->
<update id="Personne.updateOne" parameterClass="Personne.classe"> update
"PERSONNES" set "VERSION"=#versão#+1, "NOM"=#sobrenome#, "PRENOM"=#nome#,
"DATENAISSANCE"=#dateNaissance#, "MARIE"=#marie#, "NBENFANTS"=#nbEnfants#
WHERE "ID"=#id# e "VERSION"=#versão#</atualização>
<!-- excluir uma pessoa -->
<delete id="Personne.deleteOne" parameterClass="int"> delete FROM
"PERSONNES" WHERE "ID"=#valor# </delete>
</sqlMap>
O conteúdo é o mesmo do [personnes-firebird.xml], com as seguintes diferenças:
- os nomes das colunas e das tabelas estão entre aspas e são sensíveis a maiúsculas e minúsculas
- a ordem SQL " Personne.insertOne " foi alterada nas linhas 34 a 41. A forma de gerar a chave primária no Postgres é diferente daquela usada no 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. Esse valor será atribuído ao campo do objeto [Personne] designado pelo atributo [keyProperty] (linha 35), neste caso, o campo [id].
- Os comandos SQL da tag <insert> são executados na ordem em que são encontrados. Portanto, o SELECT é executado antes do INSERT. No momento da operação de inserção, o campo [id] do objeto [Personne] já terá sido atualizado pela ordem SQL SELECT.
- linhas 38-40: inserção do objeto [Personne]
A classe de implementação [DaoImplCommon] da camada [dao] é a mesma analisada na versão [Firebird].
A configuração da camada [dao] foi adaptada para SGBD e [Postgres]. Assim, o arquivo 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] agora aponta para a base [Postgres] [dbpersonnes], cujo administrador é [postgres] com a senha [postgres]. O leitor deverá adaptar essa configuração de acordo com seu próprio ambiente.
- linha 31: a classe [DaoImplCommon] é a classe de implementação da camada [dao]
Feitas essas alterações, podemos passar para os testes.
18.4. Testes das camadas [dao] e [service]
Os testes das camadas [dao] e [service] são os mesmos da versão [Firebird]. Vamos executar o SGBD no Postgres e, em seguida, os testes no Eclipse. Os resultados obtidos são os seguintes:
![]() |
Constata-se que os testes foram concluídos com sucesso com a implementação [DaoImplCommon]. Não precisaremos derivar essa classe, como foi 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 maneira semelhante à utilizada para criar o projeto [mvc-personnes-03B] com o banco de dados Firebird (ver parágrafo 17.7). No entanto, não precisamos recriar os arquivos [personnes-dao.jar] e [personnes-service.jar]. De fato, não modificamos 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 implantando 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. Usando um navegador, acessamos a URL [http://localhost:8080/mvc-personnes-04B]:

Adicionamos uma nova pessoa pelo link [Ajout]:
![]() | ![]() |
Verificamos a adição no banco de dados:

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








