Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Programando XML pelas várias camadas: Use XML na camada intermediária para obter desempenho, fidelidade e facilidade de desenvolvimento

Desenvolva uma solução em XML puro usando JDBC 4.0, SQLXML e o WebSphere Server XML Feature Pack

Andrew Spyker, Senior Software Engineer, IBM
Photo of Andrew Spyker
Como Senior Technical Staff Member (STSM) das equipes de desenvolvimento do WebSphere Application Server, Andrew Spyker concentra-se em três áreas principais. Usando seus cinco anos de experiência na liderança da equipe de desenvolvimento do WebSphere Application Server, ele orienta a equipe de desempenho. Como arquiteto de runtime SOA, ele é responsável pela manutenção da consistência nos runtimes do WebSphere SOA, concentrando-se principalmente na estratégia de avaliação de desempenho comparativa, desempenho e consistência de XML. Finalmente, na maior parte do tempo, é responsável pela criação e implementação da estratégia XML no portfólio WebSphere. Mais recente, atuou como arquiteto-chefe do WebSphere Application Server XML Feature Pack.
Bert Van Der Linden, DB2 pureXML Architect, IBM
Photo of Bert Van Der Linden
Bert Van Der Linden ingressou na IBM em 2001 para cuidar da arquitetura pureXML em DB2, o que culminou no lançamento do DB2 9 em 2006. Paralelamente, envolveu-se com muitos clientes e parceiros para divulgar o uso de XML no banco de dados e continua a trabalhar intensivamente com os clientes. Bert veio para a IBM de uma empresa iniciante, Propel, onde liderou o design e implementação do middleware distribuído e tolerante a falhas que hospedava um aplicativo de e-commerce escalável. Antes disso, trabalhou por muitos anos na Tandem Computers, no NonStop SQL, um banco de dados que executava muitos aplicativos críticos no setor financeiro.

Resumo:  Neste artigo, exploraremos uma abordagem natural e de alto desempenho para trabalhar com dados XML no banco de dados e na camada intermediária. O aplicativo da Web de exemplo combina dados XML em um banco de dados XML e em serviços Atom para explicar essa abordagem. Construiremos esse aplicativo usando um banco de dados XML, suporte JDBC 4.0 para SQLXML e o IBM® WebSphere® Application Server V7.0 Feature Pack para XML.

Visualizar mais conteúdo nesta série

Data:  26/Abr/2010 (Publicado em: 26/Abr/2010)
Nível:  Intermediário
Atividade:  4374 visualizações
Comentários:  


31 mar 2010 - Links para três vídeos adicionados no início de Recursos.

Um aplicativo de exemplo: O verificador de blog com integração a banco de dados

Vejamos o seguinte aplicativo da Web.


Figura 1. Verificador de blog com integração a banco de dados
Diagram of blog checker with database integration

Esse aplicativo da Web trabalha com dados de blog expostos em serviços de blog na Web. Os dados, contendo informações sobre todos os blogs de propriedade de um blogueiro e todos os comentários nesses blogs, são retornados em formato Atom XML (veja um exemplo na Listagem 1). O aplicativo da Web permite que um blogueiro consulte rapidamente os comentários em todos os seus blogs e exclua aqueles cujo conteúdo seja impróprio. O aplicativo da Web exibe os dados em páginas da Web e formulários XHTML. Como os dados estão em formato XML na origem e os dados do navegador também são XML (HTML ou XHTML), é natural trabalhar com os dados XML nativamente.


Listagem 1. Exemplo de feed de comentários em Atom XML

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">WebSphere Community Blog</title>
  ...
  <entry>
    <id>tag:blogger.com,1999:blog-1417695962027703953.post-6498982274841848264</id>
    <published>2009-10-17T13:06:00.000-05:00</published>
    <updated>2009-10-17T13:06:00.000-05:00</updated>
    <atom:title xmlns="" xmlns:atom="http://www.w3.org/2005/Atom" type="text">
      Questionable spamming comment title
    </atom:title>
    <atom:content xmlns="" xmlns:atom="http://www.w3.org/2005/Atom" type="html">
      Questionable spamming comment content
    </atom:content>
    ...
    <atom:author xmlns="" xmlns:atom="http://www.w3.org/2005/Atom">
      <atom:name>Joe Smith</atom:name>
      <atom:uri>http://joe.uri.com</atom:uri>
      <atom:email>jsmith@email.com</atom:email>
    </atom:author>
  </entry>
  ...
</feed>

Com o tempo, o blogueiro pode perceber que os comentários impróprios originam-se dos mesmos usuários ou do mesmo nome de domínio (como é visto no elemento atom:author da Listagem 1). Nesse ponto, o aplicativo é atualizado para permitir que o blogger, ao excluir um comentário, marque um usuário ou domínio como spammer. Como não é armazenada no serviço da Web do comentário original, essa informação deve ser persistida para um armazenamento de dados. Como os dados já estão em formato XML, é natural que sejam persistidos para um banco de dados XML. Isso permite o uso futuro do aplicativo para gerar relatórios com estatísticas de spammers específicos e fazer recomendações sobre quais comentários excluir.

Qual é a melhor maneira de implementar o aplicativo?

No passado, antes que os bancos de dados suportassem XML nativamente, havia duas maneiras típicas de trabalhar com dados XML. Em primeiro lugar, os dados podiam ser serializados para uma cadeia de caractere e armazenados no banco de dados como um character large object (CLOB). Essa abordagem tem problemas de desempenho e não permite que os dados sejam consultados dentro do banco de dados como XML.

Acrônimos usados frequentemente

  • API: Application Program Interface
  • DOM: Document Object Model
  • HTML: Hypertext Markup Language
  • HTTP: Hypertext Transfer Protocol
  • JAXP: Java for XML Processing
  • JDBC: Java Database Connectivity
  • SAX: Simple API for XML
  • SOA: Service-oriented architecture
  • SQL: Structured Query Language
  • URI: Uniform Resource Identifier
  • URL: Uniform Resource Locator
  • W3C: World Wide Web Consortium
  • WSDL: Web Services Description Language
  • XHTML: Extensible Hypertext Markup Language
  • XML: Extensible Markup Language
  • XSLT: Extensible Stylesheet Language Transformations

Em segundo lugar, os dados podiam ser fragmentados e mapeados para tabelas relacionais que representavam aproximadamente a estrutura dos dados XML. Essa abordagem tem problemas de fidelidade devido às diferenças entre a forma como os dados relacionais e XML são representados, exige que o usuário mantenha o código de mapeamento e, novamente, não permite consultas ao XML nativo. Além disso, à medida que novos requisitos impõem alterações no esquema de dados XML, alterar o mapeamento relacional geralmente é excessivamente complicado.

Dado o crescimento do uso de XML nas empresas, os bancos de dados agora estão começando a armazenar não apenas dados relacionais, mas também dados XML. Para XML, o banco de dados armazena os dados nativamente em colunas XML. Alguns bancos de dados que suportam colunas XML são Apache Derby, IBM DB2®, Oracle Database e Microsoft® SQLServer.

Além disso, anteriormente era difícil levar os dados da camada intermediária até o banco de dados. Antes do JDBC 4.0, as únicas opções eram usar os tipos de dados String ou CLOB. Como foi mencionado anteriormente, esses tipos podem causar problemas de desempenho, porque é necessário serializar os dados. Além disso, eles geralmente exigem extensões SQL não padrão para entender como analisar e inserir os dados em uma coluna XML. O JDBC 4.0 introduziu suporte padronizado ao tipo SQLXML, o que permite que dados XML sejam lidos e gravados no banco de dados em formato XML. O JDBC 4.0 permite que os dados XML sejam acessados por meio de cadeias, fluxos de leitura e gravação ou fontes e resultados JAXP. Esse suporte no JDBC 4.0 significa que os dados XML podem fluir nativamente entre a camada intermediária e o banco de dados, sem mapeamento desnecessário ou queda de desempenho no banco de dados ou na camada intermediária.

Um exemplo simples do uso do JDBC 4.0 para acessar dados XML

Examinaremos passo a passo um exemplo de uso do suporte oferecido pelo JDBC 4.0. A leitura de dados XML no JDBC 4.0 é semelhante ao trabalho com outros tipos de dados.

As etapas básicas para ler dados XML são:

  1. Criar uma instrução preparada.
  2. Executar a instrução preparada, obtendo um conjunto de resultados.
  3. Obter um objeto SQLXML do conjunto de resultados.
  4. Ler o objeto SQLXML por meio de um dos métodos get suportados.
  5. Liberar o objeto SQLXML.

Aqui está um exemplo bem básico:


Listagem 2. Lendo dados XML com o JDBC 4.0

PreparedStatement ps =
        dbConnection.prepareStatement("SELECT somexmlcolumn FROM somexmltable");

ResultSet result = ps.executeQuery();

result.next();

SQLXML xml = result.getSQLXML("somexmlcolumn");

StreamSource source = xml.getSource(StreamSource.class);

// Read from the stream source

xml.free();

Neste exemplo, a fonte é lida por meio de um objeto de origem JAXP, especificamente o StreamSource. O objeto de origem permite a leitura dos dados por qualquer API que compreenda fontes JAXP. O uso da fonte StreamSource permite o uso de qualquer representação na memória desejada. Em geral, o uso de fluxos é mais eficiente em comparação com fontes como DOM ou SAX, que acarretam processamento adicional de objetos e chamadas de API.

Da mesma forma, as etapas para gravar dados XML por meio do JDBC 4.0 são:

  1. Criar uma instrução preparada.
  2. Criar um objeto SQLXML a partir da conexão.
  3. Obter acesso ao objeto SQLXML por meio de um dos métodos set suportados.
  4. Definir o objeto SQLXML nos parâmetros da instrução.
  5. Gravar no método de acesso do objeto SQLXML.
  6. Executar a instrução.
  7. Liberar o objeto SQLXML.

Aqui está um exemplo bem básico:


Listagem 3. Gravando dados XML com o JDBC 4.0

PreparedStatement ps = dbConnection.prepareStatement(
        "UPDATE somexmltable SET somexmlcolumn = ?");

SQLXML xml = dbConnection.createSQLXML();

StreamResult result = new StreamResult(xml.setBinaryStream());

ps.setSQLXML(1, xml);

// Write to the stream result

ps.executeUpdate();

xml.free();

A camada intermediária

Como foi descrito anteriormente, a vantagem de usar um banco de dados XML (em vez de usar CLOBs ou fragmentar em dados relacionais) é o aumento do desempenho, a fidelidade XML e o desenvolvimento simplificado. O desempenho é melhor porque os dados são mantidos em um único formato em vez de serem copiados para diferentes modelos de dados, o que, no pior dos casos, exige serialização e análise adicionais. A fidelidade XML significa que a versão original inalterada dos dados XML é retida no banco de dados em vez de ser reconstruída de maneira aproximada a partir de tabelas relacionais usadas para conter os dados XML. O desenvolvimento é simplificado devido ao fato de que nenhum código de mapeamento de dados relacionais para XML é necessário.

Agora veremos a camada intermediária. Usando XML nativamente na camada intermediária, essas mesmas vantagens são obtidas na camada intermediária e, de forma ainda mais importante, pela extensão da camada intermediária e do banco de dados. Além disso, como a camada intermediária conecta-se a mais fontes do que o banco de dados XML, os benefícios podem ser estendidos a outras fontes de dados XML, como os feeds de serviços da Web.

O desempenho melhora de ponta a ponta, pois não há cópias dos dados sendo feitas entre o banco de dados (ou outra fonte de dados XML) e a camada intermediária. O desempenho em cada camada também melhora devido ao fato de que cada camada pode criar a representação de melhor desempenho dos dados XML na memória enquanto continua a oferecer modelos de programação com o padrão W3C em cima da representação dos dados.

A fidelidade também é mantida. Neste exemplo simples, a fidelidade XML pode ser uma questão secundária. Entretanto, se considerarmos que os documentos XML intercambiados podem ser algo tão complexo quanto um formulário de impostos ou tão crítico quanto um relatório financeiro, torna-se evidente a importância de garantir que os dados XML permaneçam em seu formato nativo em todas as estruturas de processamento.

Outras estruturas

Lembre-se de que há outras estruturas de persistência sobre o JDBC que suportam alguma forma de dados XML no banco de dados — tipicamente por meio do mapeamento desses dados para uma representação de objeto. Historicamente, essas estruturas tinham problemas de desempenho e de mapeamento para tabelas relacionais, como descrito acima em Qual é a melhor maneira de implementar o aplicativo?. Embora esses problemas tenham sido corrigidos pelas colunas XML e pelo SQLXML do JDBC 4.0, essas estruturas continuam a enfrentar dificuldades quando trabalham com dados XML nativamente. Em primeiro lugar, essas estruturas geralmente são mapeadas a uma representação de objeto, o que não é necessário nos casos em que o usuário deseja trabalhar com os dados XML nativamente. Em segundo lugar, elas não permitem navegação, transformações ou consultas centradas em XML depois que os dados tenham sido mapeados para objetos.

Finalmente, a simplicidade é obtida por meio do uso de um único modelo de dados em um conjunto consistente de modelos de programação XML. Embora possa ser mais fácil para um programador de Java™ na camada intermediária mapear os objetos para DOM ou JAXB em cenários simples, esses cenários não seriam tão simples nos documentos de formulários de impostos mencionados anteriormente. Além disso, o usuário teria que aprender não apenas JDBC e XML, mas também outros modelos de programação e de consulta XML. Ao trabalhar com dados XML sob coletas e resultados, o programador só precisa conhecer o modelo de dados XML e os padrões W3C para navegar, transformar e consultar os dados XML. Como XPath e XQuery já são usados no banco de dados XML para navegação e consulta, é provável que essas habilidades já sejam conhecidas.

A maneira mais fácil de alcançar esse nível de simplicidade é usar uma estrutura que lide com uma boa parte do trabalho de baixo nível de recuperar dados da fonte de dados, manipular esses dados e colocar as coisas de volta no banco de dados — sem o processamento adicional necessário para criar cópias. Para fazer isso em nosso aplicativo de exemplo, usaremos o IBM WebSphere Application Server V7.0 Feature Pack para XML. Como o XML Feature Pack pode lidar com XML no formato original a partir do banco de dados, não há nenhum impacto desnecessário sobre o desempenho. Além disso, como os dados permanecem no formato XML, o XML Feature Pack pode facilmente navegar, transformar ou consultar esses dados.

O IBM WebSphere Application Server V7.0 Feature Pack para XML

O IBM WebSphere Application Server V7.0 Feature Pack para XML introduz suporte à navegação, transformação e consulta em XML nativo usando os modelos de programação padrão W3C XPath 2.0, XSLT 2.0, e XQuery 1.0 na camada intermediária. Dada a popularidade dos dados XML na camada intermediária, queremos aplicar a abordagem de JDBC 4.0 descrita anteriormente, que não é específica a nenhum produto, ao XML Feature Pack com um banco de dados XML, como o IBM DB2 com pureXML®, Apache Derby ou Oracle Database, no seguinte formato básico:


Figura 2. Diagrama de topologia simples do XML Feature Pack e banco de dados XML
Simple topology diagram of XML Feature Pack, a network,  and XML database

Veremos como um banco de dados XML, o suporte do JDBC 4.0 para SQLXML e o XML Feature Pack suportam dados XML no banco de dados e na camada intermediária.

O cenário está disponível como um exemplo com código de origem no XML Feature Pack, permitindo que acompanhemos a explicação e experimentemos em nossos próprios aplicativos. Links para download do XML Feature Pack e do Derby, bem como do DB2 Express, podem ser encontrados em Recursos.

A combinação de suporte a XML nativo no banco de dados, JDBC 4.0 e XML Feature Pack permite adotar uma arquitetura simples e de alto desempenho.

Implementação do aplicativo de exemplo

Agora veremos como implementar esse aplicativo usando o XML Feature Pack, o JDBC 4.0 e um banco de dados XML. Primeiramente, os comentários impróprios são recuperados do blog usando o serviço da Web do blog que retorna um feed Atom (consulte a Figura 1). Durante o processamento dos comentários impróprios, as informações históricas no banco de dados são verificadas para determinar se eles são provenientes de usuários identificados anteriormente como mal-intencionados (spammers). Durante todo esse processo, os dados permanecem em formato XML. Começaremos recuperando do feed Atom as informações sobre comentários no blog.

No XML Feature Pack, os dados provenientes do feed Atom são carregados por meio de uma conexão HTTP para o serviço da Web do blogger e usados como documento de entrada para um programa XQuery. O programa XQuery é executado no tempo de execução do XML Feature Pack que foi invocado usando a API de Java do XML Feature Pack.

Os comentários impróprios são recuperados do feed Atom com a seguinte instrução XPath no programa XQuery:


Listagem 4. Instrução XPath

declare variable $comments := (
  /atom:feed/atom:entry[atom:author/atom:name = 'Anonymous'] |
  /atom:feed/atom:entry[matches(atom:content, $my:vulgarwords, 'i')])
  [atom:published > current-dateTime() - $my:monthsAgo];

Usando XPath, procuramos por todos os comentários, dentro de um intervalo de tempo definido pelo usuário, que foram postados por usuários Anônimos ou contêm palavras de baixo calão. Todas as entradas que correspondem a esses critérios são armazenadas na variável comments.

Agora, queremos ver no XQuery se um spammer está listado no banco de dados como reincidente (sendo $i uma subconsulta dos comentários acima).


Listagem 5. Instrução XQuery

let $spammedbefore := local:hasEmailHasSpammedBefore($i/atom:author/atom:email/text())

Examinando a definição dessa função, podemos ver como carregar dados XML do banco de dados.


Listagem 6. Função XQuery

declare function local:hasEmailHasSpammedBefore($emailaddress) as xs:boolean {

let $domainName := substring-after($emailaddress, '@')

return
  if ($domainName = '') then
    false()
  else
    let $jdbcURI := concat('jdbc://getAuthorsWhoHaveSpammedFromDomain?', $domainName)
    let $domainSpammers := collection($jdbcURI)
    return
      not(empty($domainSpammers/spammers/spammer/email[. eq $emailaddress]))
};

Obtemos o nome do domínio do endereço de e-mail e concatenamos o valor com uma consulta nomeada, jdbc://getAuthorsWhoHaveSpammedFromDomain, o que resulta em uma URI de coleta XPath 2.0 de jdbc://getAuthorsWhoHaveSpammedFromDomain?DOMAINNAME.

As coletas XPath 2.0 são uma maneira fácil de integrar sequências de dados XML que não são provenientes do documento de entrada principal de um programa XQuery ou XSLT. A implementação da função de coleta é definida e dependente da implementação, o que significa que o tempo de execução do XPath 2.0 pode fornecer seus próprios resolvedores de coleta padrão ou permitir que os usuários estendam o tempo de execução para fornecer implementações de coleta dinamicamente. O tempo de execução do XML Feature Pack permite que os usuários forneçam suas próprias implementações de coleta por meio da interface XCollectionResolver.

Neste exemplo, implementamos um XCollectionResolver para lidar com todas as coletas que começam com um esquema de URI jdbc:// e resolver o restante da URI contra um conjunto de consultas nomeadas definidas anteriormente. Esse resolvedor de coleta procura a consulta nomeada fornecida pelo usuário, anexa os parâmetros de posição e executa instruções JDBC contra o banco de dados.

A Listagem 7 mostra onde instanciamos esse resolvedor depois de definir algumas consultas nomeadas básicas. Também passamos uma conexão de banco de dados ao resolvedor para que ele possa operar contra qualquer conexão JDBC.


Listagem 7. Configuração do resolvedor

dbStatementsSupportsSQLXML = new HashMap<String, String>();

dbStatementsSupportsSQLXML.put("getAuthorsWhoHaveSpammedFromDomain",
        "SELECT CONTACTS from SPAMMERS where DOMAINNAME = ?");

dbStatementsSupportsSQLXML.put("updateAuthorsWhoHaveSpammedByDomain",
        "UPDATE SPAMMERS SET CONTACTS = ? WHERE DOMAINNAME = ?");

dbStatementsSupportsSQLXML.put("insertAuthorsWhoHaveSpammedByDomain",
        "INSERT INTO SPAMMERS (CONTACTS, DOMAINNAME) VALUES (?, ?)");

Connection conn = getDatabaseConnection();

JDBCCollectionResolver inputResolver =
  new JDBCCollectionResolver(conn, dbStatementsSupportsSQLXML);

A Listagem 8 mostra partes da implementação do resolvedor. Para obter a implementação completa, consulte o código de origem do exemplo no XML Feature Pack. Esse resolvedor é basicamente o mesmo que o exemplo mais simples mostrado anteriormente de leitura de dados XML por meio do JDBC 4.0.

Para ser mais reutilizável, o resolvedor adiciona o seguinte:

  1. O resolvedor procura por consultas nomeadas fornecidas externamente em vez de codificar permanentemente as instruções SQL.
  2. O resolvedor examina o tipo de metadados na linha e na coluna retornadas, garantindo que só serão lidas colunas XML com o tipo SQLXML.
  3. Finalmente, o resolvedor usa outras duas construções da API do XML Feature Pack (XSequenceCursor e XItemView) para construir uma sequência dos dados XML retornados pela consulta JDBC.

Listagem 8. Implementação do resolvedor

public XSequenceCursor getCollection(String uri, String base) {
        // look up query from query collection provided from Listing 7
        String query = lookupNamedQuery(uri);
        PreparedStatement p = dbConnection.prepareStatement(query);
        ResultSet rs = p.executeQuery();
        ...

        // Loop through the result returned from the query
        ResultSetMetaData metadata = rs.getMetaData();
        int colType = metadata.getColumnType(jj+1);
        if (colType = Types.SQLXML) {
                SQLXML sqlx = rs.getSQLXML(...);
                StreamSource source = sqlx.getSource(StreamSource.class);
                XItemView item = itemFactory.item(source);
                sqlx.free();
        }

        // Use the XML Feature Pack API to create a sequence from the returned XML data
        ...
        XItemView itemView[] = items.toArray(new XItemView[0]);
        XSequenceCursor sequence = itemFact.sequence(itemView);

        return sequence;
}

Neste ponto, temos um resolvedor de coleta razoavelmente genérico para ser usado em qualquer programa XQuery que aceite qualquer número de entradas e retorne coletas de dados XML para serem processadas por meio do XPath 2.0, XSLT 2.0 ou XQuery 1.0. Aqui estão mais dois exemplos. No primeiro, criamos uma lista de todos os spammers usando o elemento name; no segundo, retornamos o número de spammers com mais de dez postagens.


Listagem 9. Mais exemplos de XQuery

Java:
  dbStatementsSupportsSQLXML.put("getAllSpammers", "SELECT CONTACTS from SPAMMERS");
XQuery:
  let $allSpammers := collection('jdbc://getAllSpammers')
  return
    for $i in $allspammers
    let $first := $i/name/first
    order by $i/name/last
    return
      <name>
        <first>{ $first }</first>
        <last>{ $i/name/last }</last>
      </name>

Java:
  dbStatementsSupportsSQLXML.put("getAllSpamAuthorsWhereSpamCountGreaterThan",
    "SELECT CONTACTS from SPAMMERS where COUNT > ?");
XQuery:
  let $minCount := 10
  let $allSpammers := collection(concat(
    'jdbc:// getAllSpamAuthorsWhereSpamCountGreaterThan?',
    $minCount)
  )
  return
    count($allSpammers)
}

Além disso, como faz parte do XPath 2.0, o resolvedor de coleta é tão útil para o XSLT 2.0 como para o XQuery 1.0. Aqui está um exemplo simples de XSLT 2.0 usando o resolvedor de coleta:


Listagem 10. Mais exemplos de XSLT

<xsl:variable name="allSpammers" select="collection('jdbc://getAllSpammers')"/>

<xsl:template match="/">
        <p>The current spammer database contains the following domains and spammers.</p>
        <xsl:for-each select="$allSpammers">

        <table>
        <tr>
                <th>Name</th><th>Email</th>
        </tr>
        <xsl:for-each select="$allSpammers">
        <tr>
                <td><xsl:value-of select="name"/></td>
                <td><xsl:value-of select="email"/></td>
        </tr>
        </xsl:for-each>
        </table>
</xsl:template>

Da mesma forma, é possível gravar dados em um banco de dados XML. O XSLT 2.0 permite que os resultados sejam gravados em vários documentos identificados por uma URI usando a instrução xsl:result-document. Como antes, a resolução dessa URI depende da implementação do tempo de execução. Para que os usuários possam especificar onde os resultados serão gravados, o XML Feature Pack fornece a interface XResultsResolver. Neste exemplo, implementamos um resolvedor de resultados JDBC semelhante que usa instruções nomeadas e parâmetros posicionais com o parâmetro XML denotado como valor sentinela de —XML—.

Isso permite gravar dados no banco de dados como na Listagem 11:


Listagem 11. Documento XSLT resultante

<!--  Is this an insert or an update -->

<xsl:variable name="insert" select="count($spammersByDomain/spammers/spammer) eq 0"/>

<!-- Create the insert statement named query -->

<xsl:variable name="insertJdbcURI"
        select="concat('jdbc://insertAuthorsWhoHaveSpammedByDomain?--XML--&', $domain)"/>

<!-- Create the update statement named query -->

<xsl:variable name="updateJdbcURI"
        select="concat('jdbc://updateAuthorsWhoHaveSpammedByDomain?--XML--&', $domain)"/>

<!—
If insert, insert the xmldoc into the database.
Otherwise, update the database with the xmldoc.
 -->

<xsl:template match="/">
        <xsl:when test="$insert">
                <xsl:result-document href="{$insertJdbcURI}" method="xml" indent="yes"> 
                        <xsl:copy-of select="$xmldoc"/>
                </xsl:result-document>
        </xsl:when>
        <xsl:otherwise>
                <xsl:result-document href="{$updateJdbcURI}" method="xml" indent="yes">
                        <xsl:copy-of select="$xmldoc"/>
                </xsl:result-document>
        </xsl:otherwise>
</xsl:template>

Quando isso é executado no caso de um novo spammer (não existe nenhum spammer para um domínio específico), o caminho de inserção da instrução xsl:when é executado. Nesse caso, o tempo de execução XML verá uma solicitação para gravar o conteúdo da variável xmldoc na URI de resultado de:


Listagem 12. URI de resultado

jdbc://insertAuthorsWhoHaveSpammedByDomain?--XML--&domain.com

Em seguida, o resolvedor de resultados do exemplo resolve essa instrução para uma consulta nomeada que predefinimos como:


Listagem 13. Consulta nomeada

INSERT INTO SPAMMERS (CONTACTS, DOMAINNAME) VALUES (?, ?)

Então o resolvedor de resultados do exemplo anexa o conteúdo XML da variável xmldoc ao primeiro parâmetro posicional e domain.com ao segundo parâmetro posicional.

Como acontece na leitura de dados XML com coletas, a gravação de dados XML com resultados não é exclusiva de uma das linguagens XML. No exemplo anterior de gravação, o XSLT foi usado no exemplo (consulte a Listagem 11). Usando a mesma abordagem de resolvedor de resultados, pode-se direcionar um programa de XQuery 1.0 para gravar a saída em um banco de dados XML.

Uma observação sobre o uso de um Resolvedor JDBC genérico em comparação com outras abordagens

A abordagem aqui descrita, consistindo na definição de resolvedores de coleta de entrada e saída JDBC e de resultado no XML Feature Pack que são implementados pelo JDBC 4.0, é apenas uma das maneiras de implementar uma integração natural e de alto desempenho do XML Feature Pack e um banco de dados XML.

Como alternativa, é possível implementar a entrada (resolvedor de coleta) como uma função de extensão XPath 2.0 definida pelo usuário que seja mais específica, como:


Listagem 14. Função XQuery menos genérica

declare function local:hasEmailHasSpammedBefore($emailaddress) as xs:boolean {

let $domainName := substring-after($emailaddress, '@')

return
  if ($domainName = '') then
    false()
  else
    let $domainSpammers := my:getAuthorsWhoHaveSpammerFromDomain($domainName)
      return
        not(empty($domainSpammers/spammers/spammer/email[. eq $emailaddress]))
};

Essa abordagem tem a vantagem de definir mais precisamente a entrada e a saída. Suas desvantagens são a necessidade de escrever uma função de extensão para cada consulta (contra apenas uma para todas as consultas possíveis) e o fato de que ela só funciona para a entrada (escrever uma função de extensão para a saída não é natural ou possível em todos os casos). A abordagem baseada na utilização de um resolvedor de coleta e resultados mais genérico aplica-se à maioria dos casos de maneira natural e consistente.

É importante salientar que o resolvedor de coleta e o resolvedor de resultado discutidos fazem parte do código de exemplo do XML Feature Pack. Portando, o código apresentado é um exemplo. Para usar esse código em um aplicativo de produção, teríamos que expandir o exemplo de acordo com as necessidades do aplicativo.

Este artigo simplificou deliberadamente os programas XML para facilitar a compreensão. Como lembrete, o exemplo pode ser executado usando os exemplos do XML Feature Pack, que incluem o código de origem integral.

Resumo

Como foi descrito na visão geral histórica, a vantagem de usar um banco de dados XML (em vez de usar CLOBs ou fragmentar em dados relacionais) é o aumento do desempenho, a fidelidade XML e o desenvolvimento simplificado. O desempenho é melhor porque os dados são mantidos em um único formato em vez de serem copiados para diferentes modelos de dados, o que, no pior dos casos, exige serialização e análise adicionais. A fidelidade XML significa que a versão original inalterada dos dados XML é retida no banco de dados em vez de ser reconstruída de maneira aproximada a partir de tabelas relacionais usadas para conter os dados XML. O desenvolvimento é simplificado devido ao fato de que nenhum código de mapeamento de dados relacionais para dados XML é necessário.

Usando XML nativamente na camada intermediária (com o XML Feature Pack), essas mesmas vantagens são obtidas na camada intermediária e, de forma ainda mais importante, pela extensão da camada intermediária e do banco de dados. Além disso, como a camada intermediária conecta-se a mais fontes do que o banco de dados XML, os benefícios podem ser estendidos a outras fontes de dados XML, como os feeds de serviços da Web.


Recursos

Aprender

Obter produtos e tecnologias

Discutir

Sobre os autores

Photo of Andrew Spyker

Como Senior Technical Staff Member (STSM) das equipes de desenvolvimento do WebSphere Application Server, Andrew Spyker concentra-se em três áreas principais. Usando seus cinco anos de experiência na liderança da equipe de desenvolvimento do WebSphere Application Server, ele orienta a equipe de desempenho. Como arquiteto de runtime SOA, ele é responsável pela manutenção da consistência nos runtimes do WebSphere SOA, concentrando-se principalmente na estratégia de avaliação de desempenho comparativa, desempenho e consistência de XML. Finalmente, na maior parte do tempo, é responsável pela criação e implementação da estratégia XML no portfólio WebSphere. Mais recente, atuou como arquiteto-chefe do WebSphere Application Server XML Feature Pack.

Photo of Bert Van Der Linden

Bert Van Der Linden ingressou na IBM em 2001 para cuidar da arquitetura pureXML em DB2, o que culminou no lançamento do DB2 9 em 2006. Paralelamente, envolveu-se com muitos clientes e parceiros para divulgar o uso de XML no banco de dados e continua a trabalhar intensivamente com os clientes. Bert veio para a IBM de uma empresa iniciante, Propel, onde liderou o design e implementação do middleware distribuído e tolerante a falhas que hospedava um aplicativo de e-commerce escalável. Antes disso, trabalhou por muitos anos na Tandem Computers, no NonStop SQL, um banco de dados que executava muitos aplicativos críticos no setor financeiro.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=WebSphere, Information Management
ArticleID=485627
ArticleTitle=Programando XML pelas várias camadas: Use XML na camada intermediária para obter desempenho, fidelidade e facilidade de desenvolvimento
publish-date=04262010
author1-email=aspyker@us.ibm.com
author1-email-cc=
author2-email=robbert@us.ibm.com
author2-email-cc=

Conheça a IBM da sua cidade

Virtual Branch Office Brasil

A IBM está mais perto do que você imagina!


Tags

Help
Use o campo de pesquisa para encontrar todos os tipos de conteúdo no My developerWorks com essa tag.

Use a barra de rolagem para ver mais ou menos tags.

Tags populares mostra as principais tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Minhas tags mostra suas tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Use o campo de pesquisa para localizar todos os tipos de conteúdo no Meu developerWorks com essa tag. Tags populares mostra as tags principais para essa zona de conteúdo particular (por exemplo, tecnologia Java, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere). Minhas tags mostra as suas tags para essa zona de conteúdo em particular (por exemplo, tecnologia Java, Linux, WebSphere).