quarta-feira, 4 de julho de 2007

Ué? É ADODataSet ou ClientDataSet?

Olá a todos novamente.

Primeiramente quero pedir dois milhões de desculpas por não ter postado nestas últimas semanas... Mudei de emprego, estou em novo projeto e agora as coisas estão voltando para os eixos.

Indo diretamente ao assunto (o bom de escrever na net é que a reclamação só vem em forma de comentário mais tarde hehe), vou mostrar duas coisas muito legais no componente TADODataSet.


Quem conhece o TClientDataSet sabe de suas inúmeras vantagens ao desenvolver aplicativos com acesso a bases de dados (inclusive 'desconectado'). Este componente é parte da tecnologia MIDAS (google, por favor!) que principalmente visa desenvolvimento em várias camadas, sendo o TClientDataSet usado na parte de apresentação (interface), o DataSetProvider no meio e qualquer descendente de TDataSet (TADODataSet, TSQLDataSet, TBDEDataSet, etc) na parte de acesso ao servidor de banco de dados.

Além desta forma há várias outras de se trabalhar com o TClientDataSet - Isso é assunto para um (ou até mais) post inteiro dedicado a isso - Um aspecto muito interessante do TClientDataSet é que ele trabalha com dados no cache local do aplicativo, guardando as alterações feitas nos dados em um pacote transacional e aplicando tudo de uma vez no servidor quando ordenado. Outra forma é trabalhar totalmente desconectado, usando dados em memória ou de um arquivo XML. Isso é muito útil quando nós precisamos guardar parâmetros do aplicativo ou 'tabelas auxiliares' que não ficam no banco de dados.

MIDAS é uma tecnologia da Borland e se você usá-la para desenvolver deve enviar a biblioteca midas.dll junto com seu aplicativo - Quem usa Delphi 7 tem opção de compilar a MIDAS junto com o aplicativo: só adicionar a unit MidasLib na seção uses de qualquer unit do projeto.

Quem não quer (ou não pode) usar MIDAS não precisa se desesperar! O componente TADODataSet possui quase todas (senão todas) essas funcionalidades também. Com ele você pode:

- Trabalhar conectado com banco de dados;
- Enviar cada ação realizada ao banco de dados; ou
- Trabalhar no cache local e enviar um pacote transacional completo;
- Trabalhar com o DataSet em memória;
- Ler e gravar diretamente de um arquivo XML

Oba! XML! Legal! Vou fazer isso, e aquilo e zás, e zás.... Caaaaalma.....
Embora a parada do XML seja muito boa vou logo alertando: O Formato é o padrão do formato de XML ADO (não é ADO.NET) da Microsoft. Eu nunca testei, mas em teoria dá para interagir com um Recordset de uma aplicação VB ou ASP, porque é o mesmo objeto COM. Vou fazer este teste depois e mandar o resultado aqui.

Ah! Que droga! É verdade... mas o TClientDataSet é assim também. Ele usa um formato de XML padrão da Borland. Nada impede de você codificar por quilometragem e montar um super-hiper-mega-ultra programa que é o XML-o-matic que faz tudo... Eu e o Gerson estamos estudando uma forma de fazer tal coisa, mas isso é assunto para outro post (e outra viagem!).

Bem, para aqueles que tiveram paciência de ler até aqui, chegou a parte que todos estavam esperando: Vamos ver (mais ou menos) na prática.

Na Palheta ADO você encontra o ADODataSet. Ao analisar as propriedades dele repare na LockType. Os valores mais usados são ltOptimistic e ltBatchOptimistic.

O ltOptimistic é o modo de travamento de registro padrão que os outros DataSets operam e o ltBatchOptimistic também, mas com uma diferença entre eles: o ltBatchOptimistic trabalha com atualizações em cache local, enquanto o ltOptimistic leva cada alteração para o servidor de BD.

Então, para trabalhar com ele conectado no BD e a interface conectada diretamente nele, uma boa opção é usar o LockType como ltBatchOptimistic. Aí, os métodos Post e Delete não vão gravar direto no BD. Os dados vão efetivamente para o banco quando você (o DataSet) chamar o método UpdateBatch. Legal, né? Já dá pra fazer aquele mestre-detalhes complexo com um pacote transacional.

Se você trabalhar no esquema multicamadas (n-tier), onde vai usar ADODataSet na parte servidora, DataSetProvider para transmitir os dados de lá pra cá e daqui pra lá, e o ClientDataSet na parte da interface, uma boa pedida e deixar o ADODataSet como unidirecional. Com ele unidirecional aloca menos memória da aplicação servidora e faz o acesso mais rápido aos dados, já que ele só sabe mover o cursor para frente. Para fazer isso defina a propriedade CursorType como ctOpenForwardOnly. Ele trabalha como o SQLDataSet do DBExpress.

Caso você queira trabalhar com ele em memória ou com arquivo XML (ou seja, sem tomar conhecimento de servidor de banco de dados), você também pode. É Só abrir o Fields Editor (duplo-clique no componente) e ir adicionando campos da mesma forma que você cria campos calculados ou lookups, mas estes são do tipo fkData, ao invés de fkCalculated ou fkLookup. Aí, para poder ter acesso a estes dados em memória (e conectar a DBGrid, DBEdit, etc, etc e até fazer lookup é só chamar o método CreateDataSet do ADODataSet antes de trabalhar com ele.

Quando o ADODataSet está ativo (Active como True), é possível salvar o pacote de dados em formato XML ou ADTG, um formato binário proprietário da MS. Basta chamar o método SaveToFile do ADODataSet, especificando qual é o arquivo e qual o formato (pfADTG ou pfXML).

Quando você define a propriedade CommandType para ctFile você pode definir na propriedade CommandText o caminho para um arquivo XML ou ADTG com os dados (ou só a estrutura também) que ele passa a trabalhar diretamente neste arquivo. Aí, para gravar alterações é só chamar o método SaveToFile passando '' para o nome do arquivo (aí ele usa o CommandText) e o formato que está usando.

Acabou sendo um pouco mais longo do que eu pensava mas, mais uma vez, me desculpe pela grande falta nestas semanas e obrigado pela força de sempre. Como usual, a seção de comentários está à vontade. Não deixe de comentar, deixar sugestões, dicas e qualquer coisa que quiser...

Grande abraço e até a próxima.

3 comentários:

  1. legal esse post, mas o q mudou msmo minha vida foi o q falava sobre tableless! aquilo é maravilhoso!

    ResponderExcluir
  2. grande felipao!
    qdo eu acho q jah to quase chegando no 100% do conhecimento delphi, vem o felipe com seus posts boladoes!
    mandou bem!
    abraçao!

    ResponderExcluir
  3. Cara, mto irado!!!
    Resolvemos vários probleminhas com essa descoberta.
    La na Legião Estrngeira somos tolidos de usar o TClientDataSet.

    ResponderExcluir

 
BlogBlogs.Com.Br