Atenção: esse artigo tem um vídeo complementar. Clique e assista!

De que se trata o artigo:

Demonstração de como manipular tipos complexos do banco de dados sem utilizar o mapeamento para classes Java, e como retornar conjuntos de linhas através de funções com o modificador SETOF.


Para que serve:

Detalhar, através de exemplos de código, os pontos obscuros da documentação do PL/Java que descrevem os tipos complexos, promovendo um melhor entendimento da manipulação dos mesmos.


Em que situação o tema é útil:

Este tema é útil para quem deseja migrar as regras de negócio, escritas em Java, da camada de aplicação para o banco de dados, possibilitando uma maior união dos recursos do SGBD com a orientação a objetos do Java.

Neste artigo iremos mostrar como podemos trabalhar com os tipos complexos, sem utilizar o mapeamento do tipo com uma classe Java, visto no artigo sobre PostgreSQL publicado na edição 79 da SQL Magazine. Mostraremos também como é feito o retorno de várias linhas, utilizando o SETOF no retorno das funções.

A versão do PL/Java aqui discutida é a 1.4.0, com o PostgreSQL na versão 8.3.7, em ambiente Linux (CentOS 5.2).

Entrada dos Tipos Complexos

No artigo sobre PostgreSQL publicado na edição 79 da SQL Magazine, mostramos como fazer o mapeamento de um tipo complexo para uma classe Java. Este mapeamento é feito através de uma função do PL/Java, chamada add_type_mapping, disponibilizada na instalação da linguagem procedural no banco de dados.

Esta forma de mapeamento é exemplificada na Listagem 1, onde criamos o tipo complexo (linha 1) e fazemos o mapeamento com a função add_type_mapping (linha 2). Com o mapeamento feito, podemos utilizar o tipo complexo tanto como parâmetro de entrada (linha 3), como no retorno da função (linha 4). Além disso, é necessário escrever a classe Java, utilizada no mapeamento, para manipular o tipo complexo.

Listagem 1. Mapeamento de um tipo complexo para uma classe Java.


  1. CREATE TYPE complextuple AS (x float8, y float8);
   
  2. SELECT sqlj.add_type_mapping('complextuple', 'org.postgresql.pljava.example.ComplexTuple');
   
  3. CREATE FUNCTION logcomplex(complextuple)
  4. RETURNS complextuple AS
  5. 'org.postgresql.pljava.example.ComplexTuple.logAndReturn'
  6. LANGUAGE java IMMUTABLE STRICT; 

Outra maneira de passar os tipos complexos sem utilizar uma classe Java mapeada com a função PL/Java add_type_mapping, é utilizar a classe java.sql.Resultset como o tipo de dado do parâmetro de entrada no método estático da classe Java.

Em comparação com o método com mapeamento, a utilização do ResultSet deixa o código mais simples e de fácil entendimento. Em contrapartida, não teremos algumas informações disponibilizadas com o mapeamento, como por exemplo, o nome do tipo complexo que estamos utilizando.

Utilizando esta forma, o tipo complexo será sempre passado para o método Java como um ResultSet que não se pode atualizar (ready-only) e com somente uma linha. Outra particularidade no uso do ResultSet é que ele já será posicionado na única linha existente, não sendo necessário o uso do método next() para posicionamento da primeira linha.

Para recuperarmos os valores de cada coluna do tipo complexo, utilizamos os métodos padrões get do ResultSet, específico para cada tipo de dado Java. Ou seja, para o tipo int, utilizamos o método getInt(), para o tipo date, o método getDate(), e assim por diante.

Para exemplificar este uso, vamos examinar a Listagem 2. Nesta listagem, criamos o tipo complexo na linha 1 e passamos como parâmetro de entrada para a função PL/Java useComplexTest (linha 2). Esta função invoca o método useComplexTest() da classe Java Fum (linha 3). Este método recebe o parâmetro do tipo complexo e tem como saída uma String com a união dos valores de cada coluna do tipo complexTest (linha 10).

Na linha 5, podemos ver que o tipo de dado do parâmetro de entrada é um ResultSet. Sendo assim, nas linhas de 7 a 9 utilizamos os método getInt() e getTimestamp() do ResultSet ...

Quer ler esse conteúdo completo? Tenha acesso completo